2009-06-20 12 views
14

文字列を並べ替える標準的な方法に慣れていたので、Windowsは名前で名前を並べ替えることに気づいたときに驚きました。数字を含む文字列をユーザーフレンドリーな方法で並べ替える

Track1.mp3
Track2.mp3
Track10.mp3
Track20.mp3

私は(ソート時に)それらの名前が比較されていると思い手紙にとによってベース:私はあなたに例を挙げましょう数字は別に一方、次は、標準的な方法でソートされたリストと同じである


Track1.mp3
Track10.mp3
Track2.mp3
Track20.mp3

私はしたいと思いますDelphiで同じように文字列を並べ替える比較アルゴリズムを作成します。最初は、文字の間に2つの文字列の連続する文字を比較するだけで十分だと思った。桁が両方の文字列のある位置に見つかると、その桁に続くすべての桁を読み取って数値を作成し、数値を比較します。

あなたの例を与えることを、私は「Track10」と「トラック2」の文字列こうして比較します:彼らは同じである一方で、彼らは手紙いる間
1)文字を読む:「トラック」、「トラック」
2)数字が見つかった場合は、 "10"、 "2"
などの数字をすべて読み取る。2a)等しい場合は1に進み、そうでない場合は
10が2より大きいため、 "Track10"は"Track2"

私のテストでは、Windowsが "Track10"よりも "Track010"を低いと見なすまで、すべてのことが正しいと思われました。最初のものはg私のアルゴリズムによれば、両方の文字列が等しくなることは間違いであるとは言えません)。

Windowsが名前でファイルをどのように並べ替えているのか、あるいは私が基礎を置くことができる(プログラミング言語で)すぐに使えるアルゴリズムを持っているかという考えを私に提供できますか?

ありがとうございます!
マリウスズ

+1

多くの他の質問の重複:http://stackoverflow.com/questions/34518/natural-sorting-algorithm –

+2

申し訳ありませんが、私は以前に検索するフレーズを知りませんでした。これが無意識のうちにこの質問を複製した理由です。今私はこのソート方法を「自然分類」と呼んでいることを知っています。それで、自分でそれに関するいくつかの情報を検索することができます。 –

+0

これを見てくださいhttp://stackoverflow.com/questions/31538293/sorting-listfileinfo-in-natural-sorted-order –

答えて

17

ジェフはコーディングホラーでこれについての記事を書いています。これはnatural sortingと呼ばれ、数字のグループを単一の「文字」として効果的に扱います。太陽の下であらゆる言語に実装されていますが、不思議なことに、ほとんどの言語の標準ライブラリには通常組み込まれていません。

+4

ありがとう手掛かりのために。私は、私が探していたWindows API関数StrCmpLogicalW(http://msdn.microsoft.com/en-us/library/bb759947.aspx)を見つけることができました。 –

+0

ここにPHPの実装があります:[natsort](http://php.net/manual/en/function.natsort.php) –

0

あらゆる種類の母:

ls '*.mp3' | sort --version-sort

1

絶対最も簡単な方法は、私が見つけた、そう、あなたがしたい文字列を分離しました。 OPの場合、Path.GetFileNameWithoutExtension()は、非数字を削除し、intに変換してソートします。 LINQといくつかの拡張メソッドを使用すると、1つのライナーになります。RemoveNonDigitsとToIntOrZeroは、拡張メソッドである場合

Directory.GetDirectories(@"a:\b\c").OrderBy(x => x.RemoveNonDigits().ToIntOrZero()) 

:私の場合、私は、ディレクトリに起こっていた

public static string RemoveNonDigits(this string value) { 
    return Regex.Replace(value, "[^0-9]", string.Empty); 
} 

public static int ToIntOrZero(this string toConvert) { 
    try { 
     if (toConvert == null || toConvert.Trim() == string.Empty) return 0;    
     return int.Parse(toConvert); 
    } catch (Exception) { 
     return 0; 
    } 
} 

拡張メソッドは、私はどこでも使用する一般的なツールです。 YMMV。

+0

非常に良い回避策です。私のために働いた!ありがとう! – Pedro77

関連する問題