先日行われた、わんくま同盟 東京勉強会 #4 で「オブジェクト指向ってなんだ in 東京」というタイトルのパネルディスカッションがありました。
その中で、次のような話をされた方がいらっしゃったように記憶しています。(記憶違いだったらごめんなさい)
- 最近は様々な機能が実装されていて便利になった。
- 例えばソートなどはコレクションクラスなどの中に最初から実装されている。
- つまりは自分でソートロジックを組まなくてもよい。
- とっても便利だ。
- 一方で、ソートロジックって何?、という人が増えてきている。
僕は、ただただ「なるほど~」と皆さんの話を興味深く聞いていた訳です。
そんな折に、つい先ほど、お客さんからの質問で以前作ったソースコードを眺めていたところ、偶然にも昔(VB5くらいの頃かな?)作った
シェルソートルーチン
が見つかっので、C# に移植してみました。
「今さら何の役に立つんだ?」とか「何でクイックじゃないの?」という話は置いておいて、取りあえず晒してみることにしました。
static public string[] ShelSort(string[] values) {
int l = values.Length;
int g = (int)(l / 2);
while (g > 0) {
for (int i = 0; i <= g; ++i) {
for (int j = i + g; j < l; j += g) {
for (int k = j - g; k >= i; k -= g){
int p = k + g;
if (values[p].CompareTo(values[k]) > 0) {
break;
}
string T = values[p];
values[p] = values[k];
values[k] = T;
}
}
}
g = (int)(g / 2);
}
return values;
}
さて、いくつか気になるところです。
まずは、当時は高速化を意識して変数名などを小さくしたり、メソッドアウトせずに作ったので可読性が悪いなぁ、という点。
次に、可読性が悪いため、移植後にあまりよく確認していない点w
(ちゃんと動くのか?)
それと、[p][k]要素の入れ替えって、.NetFramework でそういうメソッドって用意していないんだろうか?、と思われる点。
(見つからなかった orz)
最後に、CompareTo の部分はデリゲートを使って、最小順位の方法を使う側に行わせたいなぁ、と思った点。
(これも、可読性が悪くて、深くは考えるの面倒くさいw)
static void Main() {
string[] a = { "ccccccccc", "bbbbbbbbb", "aaa", "dddddddd" };
foreach (string s in a) {
Debug.WriteLine(s);
}
a = ShelSort(a);
Debug.WriteLine("--------------------");
foreach (string s in a) {
Debug.WriteLine(s);
}
}
一応、上記で確認してみたところ、きちんと並べ替えできましたけど・・・
ちなみに、シェルソートの意味ですが、タイトルのように貝殻を並べるということではなく、考案者の名前にちなんでいるようです。
僕はてっきり、並べ替える処理が貝殻の形みたいになるからという理由だと思っていました。