■
数字混じり文字列ソート
で、なんで、Char.IsNumberについて見てたのかといえば、
というか、
が気になったから。
これ、どう見ても、正規表現を使い始めたら、.NETに勝ち目はない。Regex クラスの使い勝手の悪さに対処しているだけで精一杯。
そして、Linq的な処理を考えようにも、IEnumerable
結局、昔ながらの文字解析を行った方が順当っぽい。
ということで、Linqスタイルとか、そういうのを全部無視して、素直にArray.Sortに渡す比較関数を考えてみることに。
static bool isDigit(Char c) { return c >= '0' && c <= '9'; } static int extractNumber(String a, ref int pos) { int end = pos; while (end < a.Length && isDigit(a[end])) end++; int ret = int.Parse(a.Substring(pos, end - pos)); pos = end; return ret; } static int compare(String a, String b) { int iA = 0, iB = 0; int lenA = a.Length; int lenB = b.Length; while (iA < lenA && iB < lenB) { Char cA = a[iA], cB = b[iB]; if (!isDigit(cA) || !isDigit(cB)) { int d = (int)cA - (int)cB; if (d != 0) return d; } else { int vA = extractNumber(a, ref iA); int vB = extractNumber(b, ref iB); int d = vA - vB; if (d != 0) return d; } iA++; iB++; } return (lenA - iA) - (lenB - iB); }
うーん、パフォーマンスは出そうだけど、微妙なコードだなぁ。