2012/03/31(土)C# で PriorityQueue を使いたいので
Dijkstra とか教科書通りに書きたいとき。コピペしていいプロコン用に。
public class PriorityQueue<T> {
List<T> list = new List<T>();
IComparer<T> comp = Comparer<T>.Default;
class Comparer : IComparer<T> {
Comparison<T> comparison;
public Comparer(Comparison<T> comparison) { this.comparison = comparison; }
public int Compare(T x, T y) { return comparison(x, y); }
}
public PriorityQueue() { }
public PriorityQueue(Comparison<T> comp) { this.comp = new Comparer(comp); }
public void Enqueue(T item) { int i = list.BinarySearch(item, comp); list.Insert(i < 0 ? ~i : i, item); }
public T Dequeue() { T r = list[0]; list.RemoveAt(0); return r; }
public T Peek() { return list[0]; }
public int Count { get { return list.Count; } }
public T this[int i] { get { return list[i]; } set { list[i] = value; } }
}
public class Program { // てすと
class A : IComparable<A> {
public int X;
public A(int x) { this.X = x; }
}
static void Main() {
PriorityQueue<A> Q = new PriorityQueue<A>((x, y) => y.X - x.X); // でかい順
Q.Push(new A(1));
Q.Push(new A(3));
Q.Push(new A(2));
Q.Push(new A(1));
Console.WriteLine(Q.Pop().X);
Console.WriteLine(Q.Pop().X);
Console.WriteLine(Q.Pop().X);
Console.WriteLine(Q.Pop().X);
}
}
中の構造に単純な配列を使ってるのでPushとPopでメモリコピーが発生してO(N)なのがどうかなー。
状態数が多くなるならちゃんとヒープ作るべきなのかも。
SortedList は、キーが重複できないのでいやーんな感じ。
つーか、もうちょっとスニペットを充実させておきたいなぁ。
2010/05/31(月)最適化実験+1
クラスライブラリ側がVector3(float, float, float)を要求するとき、
それをラップするクラスはどうするべきかと考えていた。
さらに、内部の型が違う場合について調べてみた。
2010/05/30(日)最適化実験
暗黙的型変換の最適化に関する実験。
2010/05/03(月)mp3infp を C# で使うためのクラスライブラリ
TCO Q.Round1 が rescheduled だったのを知らなかったので、
mp3infp.dll を C#から使えるようにポーティングしていました。
C#からMP3ファイルのタグ情報を取得したいなぁと思ったのですが、
自前でフォーマット読んであーだこーだやるよりは、ライブラリで確実にと。
いつもタグエディタとして大変お世話になっているmp3infpに頼ることにしました。
このクラスライブラリの特徴
- mp3infpが扱えるすべての形式に対応。
- Unicode形式の保存にも対応。
- ソースコードをあなたのプロジェクトにコピペするだけで使える。
- ゆるゆるライセンス
例
// タグ情報を読み込んで表示してみる。
Environment.CurrentDirectory = @"E:/Music";
TagInfo tag1 = MP3infp.LoadTag(@"[丹下桜] SAKURA/14. New Frontier.mp3");
Console.WriteLine(tag1.Title + " / " + tag1.Artist);
とか
// ID3v2 タグを ID3v1タグにコピーしてみる
MP3infp mp3infp = new MP3infp(@"E:/Music/[水樹奈々] PHANTOM MINDS/02. Don't be long.mp3");
// ID3v1がなかったら作る
if (!mp3infp.ContainsMP3Tag(MP3infp.MP3TagType.ID3v1))
mp3infp.AddMP3Tag(MP3infp.MP3TagType.ID3v1);
TagInfo tag_v1 = mp3infp.LoadTag<TagInfo.MP3_ID3v1>();
TagInfo tag_v2 = mp3infp.LoadTag<TagInfo.MP3_ID3v2>();
// コピー元とコピー先で共通して有効な項目のみコピーして保存。
TagInfo.Copy(tag_v2, tag_v1);
tag_v1.Save();
// ID3v2はUnicodeに変換して保存。
tag_v2.SaveUnicode();
とか、そーいうことをC#からできるようになります。
mp3infpのお陰で、mp3ファイルのID3v1,ID3v2の他、RMPやOGG, WAV, AVI, mp4 などにも対応できるのが嬉しいですね。
素晴らしいプログラムをありがとうございました。
次のソースコードをプロジェクトに追加するだけで使えるよーになります。
ダウンロード
本体: mp3infp.cs (GitHub)
ライセンス: NYSL / http://www.kmonos.net/nysl/
動作に必要: Win32工作小屋 - mp3infp / http://win32lab.com/fsw/mp3infp/
mp3infp自体はLGPLですので、配布の際はご注意ください。
2009/02/26(木)実験 - デリゲートの渡し方
匿名メソッドの速度とか、どう渡すのが一番速いのかなー。
ちょっと気になったので。(1)~(4)で一番速いのはどーれだ。
class Test
{
class A { public int a; }
class B : A { }
void DeA(A obj) { obj.a++; }
void DeB(B obj) { obj.a++; }
void DoB(Action<B> act) { act(obj); }
DoSomething()
{
DoB(DeA); // (1)
DoB(DeB); // (2)
DoB(delegate(B obj) { obj.a++; }); // (3)
{ // (4)
Action<A> act = delegate(A obj) { obj.a++; });
DoB(new Action<B>(act));
}
}
}
それぞれ1000万回の実行時間を計った。
2009/02/08(日)指定した正規表現にマッチしなくなる操作をキャンセルするテキストボックス
追記: TextBox.Validatingでできそうです。車輪の再発明だった模様。
指定フォーマットを入力させたいとき、MaskedTextBoxは便利なんだけど、int型を受け取りたいとか、double型を受け取りたいとかそういう目的にはイマイチ使い勝手が悪いような気がしたので作ってみた。
たとえば、ユーザにdouble型を入れて欲しい場面があった。
ユーザがちゃんと入れてくれることを信じるわけにはいかないので、double.TryParseでエラー処理を書くのはもちろんなのだけど、その前の段階で少しでもエラーをサプレスできないかなと思った。
そして好奇心からごりごりとWin32で作ってみた。
デザイナで配置してRegExPatternプロパティに
^-?\\d*(\\.\\d*)?$
とか、書く。操作後マッチしなくなるような操作は受け付けない*1。Win32で作ったので、x64では動かないかもしれない。WindowsXPでは動いてるが、他のバージョンでは動かないかもしれない。そんなことをするくらいなら、素直にTryParseのエラー処理だけしておくべきなのだとも思うが。まぁ、好奇心だから。
最近、Win32のプラットフォーム呼び出しにあんまり抵抗がなくなってきた。やばいなぁ。