カテゴリー
Programming

C# の文字列ソート

つい忘れてしまうのでメモっておきます。
.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{|}~

カテゴリー
Programming

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

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 も解釈してくれませんが。(だめじゃん)

カテゴリー
Programming

LXRのbaseurl

LXR (Linux Cross Reference)は設定ファイルの項目baseurlをもとに、
HTMLのbase要素を通じてスクリプトへのパスをブラウザに伝える。
もし、LXRを閉じたネットワークに設置して内部から利用し、
さらに外部からもSSHのポートフォワーディングなどで
利用する場合、色々なホスト名でアクセスされることになる。
しかし、単にbaseurlに”/lxr/”などと相対パスを書いても
base要素のhref属性としてはブラウザに正しく解釈されず、
おかしな挙動が起きてしまう。
この場合は、LXRのlib/LXR/Common.pmのbaseurlサブルーチンを


sub baseurl {
return('http://'.$ENV{'SERVER_NAME'}.
':'.$ENV{'SERVER_PORT'}.
$Conf->baseurl);
}

などと書き換えて絶対パスにしてやればよい。

カテゴリー
Programming

Camomile

CamomileはOCaml用のUnicode処理ライブラリです。
GODIにも入っていて簡単に取得して使い始めることができます(今は0.6系の模様)。
このソフト、APIマニュアルは公開されているのですが、以前からあんまり
サンプルコードやチュートリアルがなくてとっつきにくかったので、
ちょっとサンプルコードつきの説明を書いてみました。
Camomile