Since 2005/9/19 Last Updated 2005/11/9
語を辞書の順にソート(並べ替え、整列)するというのは、一見簡単なようでなかなか難しい。「そんなの、Excelのデータ(D)-並べ替え(S)で一発じゃん?」と思うかもしれない。たしかに、最近のアプリケーションでは、ExcelからDOSのSORTコマンドに至るまで、当たり前のように辞書順ソートをしてくれるようになったので、問題の複雑さがわかりにくくなっているが、これらに頼らず、プログラミング言語やマクロなどを用いて自前でソートをしようとすると、とたんに難しい問題に直面する。単に文字列の大小を比較して並べ替えたのでは、コード順のソートになってしまい、辞書順にはならないのだ。 コード順と辞書順とはどう違うか、次の例を見てもらいたい。
これを防いで辞書順にするためには、濁点の有無、大きい仮名(や・ゆ・よ…)と小さい仮名(ゃ・ゅ・ょ…)との区別、ひらがなとカタカナとの区別などをひとまず無視したソートを行い、その上で、濁点のあるものとないものとどちらを先にするか、などの優先順位をつけるようにしなければならない(ところで、上記の辞書順はExcelを用いたのだが、「きゃく」<「きやく」というのは一般の辞書で採用されているのだろうか。ふつう「きやく」<「きゃく」だと思うのだが)。 この問題は日本語の文字が複雑だからではない。英語だって同様。たとえば英語では、ASCIIコード順でソートすると、大文字で書かれたものが前になってしまい、Zで始まる語がaで始まる語の前になってしまうという事態が生じる。だからまずは、大文字・小文字を無視したソートを行い、そのうえで、大文字のものと小文字のものとの優先順位をつけるようにしなければならない。 あとは英語の場合、複合語など、「スペースで区切る」「ハイフンで区切る」「区切りなし」などのヴァリエーションが生じるが、これらの順序を正しく処理することも必要だろう。単にコード順でソートすると、記号のために思わぬ順序にソートされてしまう。まずは記号類を一切無視してソートし、そのうえで記号の有無による順位付けをすることだろう。また、最初の語のあとにもってくるという流儀もあろう。 こんなふうに、辞書順ソートというのはなかなか大変なのである。Excelなどのアプリケーションは、けっこう複雑な処理をしているのだ。 当サイトは「インドの言語を言語を勉強する人のための〜ページ」なので、最終目標はサンスクリットやウルドゥー語、ヒンディー語などの辞書順ソートの実現である。だが急がば回れ、まずはひらがな、カタカナの辞書順ソートのやり方を考えてみよう。 上でちらっと書いたように、辞書順ソートとは2段階の手順をふむソートである。つまり……
問題は2.の「優先順位」。要は上記のような順位をつけられればよいわけである(私はやはり小さい仮名のほうが大きい仮名より前に来るというのは抵抗があるが、いまそれは置く)。 上記のように、同じく「きやく」になってしまうデータだけを抽出して、それらの中で優先順位をつけようとすると、けっこう処理が複雑になってしまうし、時間がかかる。そこで、他のデータと同じになろうとなるまいと、ともかくすべてのデータについて、文字の種類に応じてたとえば次のような値を算出してしまう。これを「重み」と呼ぶことにしよう。 さらに、単に文字列を重みに変換したのでは、たとえば文字列が20文字あれば、重みの値も20文字になってしまう(下の表の「重み1」)。どうせ数字なのだから、すべて足しこんでしまおう。そうすれば桁数を節約できる(下の表の「重み2」)。 もっとも、単に足したのでは、ひらがな大文字2文字の重みと、ひらがな濁点1文字のデータの重みとが同じになってしまう。下の表を見てもらえばわかるように、うまく順位付けできていない。でも要はひらがな統一文字列で同じになるものどうしの順番さえ確定すればいいのであり、同じになってしまう文字列の発生は実際にはありそうでなかなかないので、実用上はこれでも差し支えないと思う。 気になるのであれば、各文字について重みの種類は8つなので、足しこんでいく際に、前の重みに8をかけながら足していくというような方法も考えられる。下の表の「重み3」がそれであるが、うまく順位付けがなされているのがわかるだろう。もっとも、かけていく値を大きくしてしまうと、このような工夫の意味がなくなってしまう。たとえばかけていく値を10にしてしまうと、ずばり重み1と全く変わらない数値になってしまい、工夫の意味がなくなってしまうので要注意。 さらに、上で「ひらがな統一文字列を第一キー、重みを第二キーとしてソート」と書いたが、実際にはひらがな統一文字列と重みを連結してしまえばいい。重みの最大値がたとえば4桁でおさまるなら重みの数字を4桁に統一して文字列に変換してしまい、ひらがな統一文字列のあとにくっつけてしまう。念のためスペースを一個はさむなどしておけば十分である。これに基づいてソートすればいいわけである。
上記のように、いくらコンピュータの文字コードがうまく設定されていても、それをそのままソートに用いるわけにはいかない。 Unicodeのデーヴァナーガリーのコードはけっこううまくできていて、そのままソートすればそれなりにヒンディー語やサンスクリットの順になってくれるが、細かいところで辞書順とは異なる(だいたい、ヒンディー語とサンスクリットではソートの仕方が違うのだ。その件は「サンスクリットのソート」を参照)。 まして、Unicodeのアラビア文字のコード順は、ウルドゥー語の順序と異なるところがあるので、ウルドゥー語ではそもそもUnicodeでソートすることは不可能。 さらに、サンスクリットやパーリ語ではローマ字を用いることが多いし、データベースソフトによってはUnicodeを用いることができず、ヒンディー語やウルドゥー語をもローマ字転写の形でデータ化したりすることも多い。このようなローマ字の順番でソートしても辞書順とはまるきり異なる結果になるのは自明である。 そこで、ソートするときには、Unicodeやローマ字などで表現された語を、辞書順に並ぶようなコードに変換し、そのコードでソートをすることになる。具体的には、このページの最後にあるような数字列に変換する。この数字列はあくまでソート用の内部的なものであり、さらに別の形で参照することはない。できれば、Unicodeやローマ字などから自動的に変換できるような形にしたい。 さて、いよいよウルドゥー語のソートの話である。 ウルドゥー語は通常、短母音表記をしないので、同じつづりになってしまう語がいろいろある。これらの間の順位付けをどうするかも問題になろうが、いろいろな辞書を見るとまちまちで、特に基準らしいものはありそうにない。そこで母音記号類は一切無視することとする。 で、母音記号を除いた文字の順序は次のとおりである。 いよいよウルドゥー語ソートの実現である。ここでは当サイトの語彙集で実際にやっている方法を述べることにする。
ヒンディー語やサンスクリットのソートについては稿を改めて記す。 |