2011年11月25日金曜日

( C# ) 日付のクイックソートなど

私はだいたい、めんどくさい処理を書いてそいつをコンピュータにやらせている。
例えば何度もループすることや、大きな整数計算。画像処理や一括処理などがそうだ。
私なんかがサクサクプログラミングできるのだからプログラミング手法は年々より効率的な
ものになっているのだと思う。
しかしながら、こういっては失礼かもしれないが

”めんどくさい処理をあらかじめ書いておきそれを実行させる。”

これは未だに変わっちゃいない。統合開発環境などでデザイナを使ってると一見自動で
プログラミングされているように見えるが、これもやはり、そうなるようにそういった処理をあらかじめ書いてあるのである。

で、だから何だという話だが

”実行させ、めんどくさい処理を書かせ、結果のみ返す”

ようになればこれって革命だよなぁとふと思ったわけです。

あれ?でもその仕組作るにはまためんどくさい処理を自分で書かなきゃならないわけで…
…自分で何考えてるかこんがらがってきた。まぁどうでもいいことなんですけど...。


はい、さて、タイトルの件ですが、C#で画像ファイルの日付によるクイックソートは

Array.Sort(Array array,  IComparer comparer)

を使えば簡単でスッキリとかけるのだが、自分で書いたほうがもっと速いんじゃないかと思ったので自作クイックソートを書いてみた。

//クイックソート
private string[] quickSort(string[] filename, DateTime[] days, int left, int right)
{
    Stack<int> lstack = new Stack<int>(right - left + 1);
    Stack<int> rstack = new Stack<int>(right - left + 1);
    string work;
    DateTime work_time;
    int end = right;

    lstack.Push(left);
    rstack.Push(right);

    while (lstack.Count != 0)
    {
        int pl = left = lstack.Pop();
        int pr = right = rstack.Pop();
        DateTime pivot = days[(left + right) / 2];
        do
        {
            while (pl <= right && days[pl].CompareTo(pivot) < 0) {pl++;}
            while (pr >= 0 && days[pr].CompareTo(pivot) > 0) {pr--;}
            if (pl <= pr)
            {
                work_time = days[pl];
                work = filename[pl];

                days[pl] = days[pr];
                filename[pl] = filename[pr];

                days[pr] = work_time;
                filename[pr] = work;
                pl++; pr--;
            }
        } while (pl <= pr);

        if (left < pr)
        {
            lstack.Push(left);
            rstack.Push(pr);
        }
        if (pl < right)
        {
            lstack.Push(pl);
            rstack.Push(right);
        }
    }           
    return filename;
}

引数は順にファイル名、そのファイルと同じ順番のDateTime配列、開始位置、終了位置
である。で問題の速度差なんだけど...なんと!

ほとんど変わりません。

ファイル数が少ないからかなぁ?まぁ速い遅いどちらにせよどこかで使うかもしれないので
メモ。