C# の文字列ソート

August 17, 2008
つい忘れてしまうのでメモっておきます。

.NET Framework の String.CompareTo(String) は Char.CompareTo(Char) と異なる基準で文字を比較します。List<String> と List<Char> に ASCII 文字をつっこんで List<T>.Sort() すると一目瞭然です。List<T>.Sort() はデフォルトで CompareTo 使うため、これで違いを確認できます。


using System;
using System.Collections.Generic;
...
List c_list = new List();
List s_list = new List();

for (int i = 0; ' ' + i <= '~'; i++) {
char c = (char)(' ' + i);
c_list.Add(c);
s_list.Add(new string(c, 1));
}

c_list.Sort();
foreach (char c in c_list) {
Console.Write(c);
}
Console.WriteLine();

s_list.Sort();
foreach (string s in s_list) {
Console.Write(s);
}
Console.WriteLine();




結果は以下です。


!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
'- !"#$%&()*,./:;?@[]^_`{|}~+<=>\0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ




List<Char> のほうは ASCII コード順にソートされていますが、List<String> のほうはなにやら愉快なことになっています。

String.CompareOrdinal() という Char.CompareTo(Char) と同じ基準で比較をするスタティックメソッドがあるので、これを delegate にして渡してやると同じ結果になります。


s_list.Sort(delegate(string a, string b) { return string.CompareOrdinal(a, b); });





!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~



En Google modified by Gulfweed 0.06

August 14, 2008
仕様変更に対応しました。

インストール

正常に更新されない場合は一度 Greasemonkey を無効にして
上記リンクを開き、強制リロードをかけてください。

En Google modified by Gulfweed 0.05

December 11, 2007
日本語インターフェースの仕様が変わったので対応しました

En Google modified by Gulfweed

正常に更新されない場合は一度 Greasemonkey を無効にして
上記リンクを開き、強制リロードをかけてください

原作者: ユーザJavaScript - namespace gimite

MinGW で64bit整数を printf するときの注意

September 14, 2007
MinGW は Windows の C Library (MSVCR) を使うので普通は %lld を解釈してくれません。Cygwin から開発をしていると、この事を忘れてはまり易いので注意。
(環境 : Windows 2000 + gcc 3.4.5 (mingw special))

VC++ と同じように %I64u, %I64d を使えば大丈夫です。C++ コードならストリームを使えばとりあえず問題ないとのこと。

Google:MinGW lld I64d で関連情報がたくさん出てきます。

これは使用するランタイムを選択することでも解決できます。最新の MinGW Runtime をインストールし、Wrapper として libmsvcr80.a をリンクすることで MSVCR 8.0 を使えば %lld も正常に解釈されます。libmsvcr71.a 以前はだめです。



printf の話題なのでついでに

%llf は多くの C Library で結果的に拡張倍精度長浮動小数点数 (long double) の format として機能しますが、本来 long double の変換修飾子は L です。日頃から %Lf を使うようにした方が無難かと思います。

これはたとえば GNU C Library なら vfprintf.c のソースから is_long_double 周辺を見ればよくわかります。

MSVCR は %Lf も解釈してくれませんが。(だめじゃん)

ICFP 2007 延長戦

July 30, 2007
damaC# というチームで参加していましたが、
期間中はまともなスコアを出すことが出来ませんでした。

しばらく延長戦をやっていたので
その成果を公開してみます。

http://starlancer.org/~ysn/damacy/

前5件

次5件