コンテンツへスキップ
ものがたり
戻る

2005-07-01

IndexOf() - unstable algorithm

expansionに大ハマりです。

今、こんなAPIがあるとします。まあCompareInfoなんですけど。

int IndexOf (string source, string target)

で、引数に”\u00E6”を渡すことを考えます。ちなみにU+E6はaとeの合字です。なので、

IndexOf (“01234\u00E6”, “ae”)

は5を返します。じゃあ問題。↓は何を返すべきでしょうか?

IndexOf (“ABC\u00E6”, “e”)

U+E6はaとeの合字だから、ABCaの次だから…4?? そんなわけありません。戻り値はあくまでsourceのインデックスを返さなければならないはずです。

ちなみに.NETのCompareInfoは-1を返します。なるほど、それはアリなのか。そう思って↓をやってみると

IndexOf (“ABC\u00E6”, “a”)

これは3を返したりして。もうワケが分かりません。

ええと、1文字分以上のsortkeyの配列定義もつ1つ以上のcharの順列を「文字要素」と定義すると、たぶんIndexOf()は、対象となるtargetの先頭の文字要素にマッチする文字要素を包含する文字要素1のインデックスを返すべきなのかな、と思う。つまりIndexOf(“ABC\u00E6”, “e”)は”a”と同じ3を返すべきじゃないかな、と思う。

ただし、その設計では、IndexOf(s, t)の戻り値nについてIsPrefix(s, t, n, s.Length - n)が必ずしも成立しない、という問題がある。これは特にIndexOf()を実装する側が内部的にこのIsPrefix()を用いることが出来ないので辛い。同様に、一体どういう処理ならばこの戻り値を適切に利用できるのかという疑問が常につきまとう。

結局IndexOf()っていう機能自体が、intを返すなんていうお手軽なAPIで実装できるほど簡単なものではないはずなのだ。

IgnoreCase + tailoring

これってUCAでは出来てるんだろーか。要検討。

IsSuffix() - unstable algorithm

バグだらけじゃんWindows。


コメント

とおりかかりましたが — 07/02/2005 01:35:37

aeはaという扱いなのかな?eはアクセント記号みたいな。

atsushieno — 07/02/2005 02:05:32

いえ、U+E6のaとeはどちらも独立した文字であり、このae(U+E6)は分離できない文字ではありません。何でそう断言できるのかというと、CompareInfoクラスのGetSortKey()というメソッドが返すバイナリ値が、”ae”というASCII文字列と同じ、2文字分の値を返すからです(aeがaという扱いで、eがアクセント記号だとしたら、Windowsのsort keyの値は文字1つ分になります)。

もっとも、アクセント記号として使えるeというのは存在していて、実際UnicodeでU+0364として定義されています。
http://www.fileformat.info/info/unicode/char/0364/index.htm

似て非なるものに、contractionというものがあって(どう日本語訳すればいいんだろう?)、たとえばハンガリー語の”zs”というのはzとsには分離できません。GetSortKey()は、”zs”に対しては1文字分のバイナリ値しか返しません。これはあなたの想像する「zsは△※□という扱い」に近いものです(英語のアルファベットには相当する文字は無いので△※□)。

atsushieno — 07/02/2005 02:08:02

補足: ええと、U+364について何が言いたいかというと、eがアクセントというのは良い推測ではないか:-)ということと、でもそれは別の文字なので(Unicode Character Databaseでも関連性は無いです)、U+E6の話とはあてはまらないだろう、ということです。

Footnotes

  1. あーややこし。ここが「文字」ではなく「文字要素」なのは、source側のcharが常にchar1つとは限らないため

  2. zsはcontraction


この記事を共有:

前の記事
IgnoreCase + tailoring
次の記事
IndexOf() - unstable algorithm