ejdic2knotsort.txtの内容は次のようなものです。2002件あります。
ejdic2k.txtのabc順になっていないものです。リンクを右クリックして出てくるメニューから「名前をつけてリンク先を保存」を選ぶことで、javaプログラムを入れるフォルダにダウンロードしておきましょう。
英単語と意味の間はタブで区切ってあります。
a 一つの,ある complicate …'を'複雑にする clothe …‘に'衣服を着せる,…'を'すっかりおおう,一面におおう upset …‘を'ひっくり返す,だめにする,心お乱す,転倒,混乱 frighten …‘を'ひどく驚かせる,おびえさせる,ひどく怖がる think …‘を'考える,思う,…‘を'企てる,考える can …することができる,…であり得る,…してもよい whenever …するときはいつでも;,いち…でも because …だから,…ゆえに,であるからといって would …だろう,…するつもりである,…したものだった,…したい at …で,…に,…の最中で,…の状態に,…を目指して,…によって without …なしに,もし…がなければ,…を外に,…[の限度]を越えて though …にもかかわらず,たとえ…でも,もっとも…ではあるが to …に対して,…まで,…のために,…へ,…に toward …のほうへ,…のほうに,…近く,…に対して .....................省略.........
ファイル読み込み部分は Jiten05.java または Jiten04.java とほとんど同じです。
並べ替え部分は Koukan05.java とほとんど同じです。ただし途中経過は i が変わった時に word[i] と i の値を表示しています。 Koukan05.java のままだと 2002個のデータを表示しますから多すぎるからです。また、並べ替えた結果の報告は最初の数行と最後の数行だけにしています。これも多すぎるからです。
? の部分は Koukan05.java と同様に書き換えます。
一部全角のスペースが紛れているようです。半角に直してください。「\12288 は不正な文字です」の \12288 は全角スペースのことです。
import java.io.*;
public class DicSort01 {
public static void main( String[] args ) {
//Jiten05.java のファイル読み込み部分
String fname = "ejdic2knotsort.txt";
String[] word = new String[2010];
String[] imi = new String[2010];
int ct = 0;
try {
FileReader in = new FileReader(fname);
BufferedReader inb = new BufferedReader(in);
String line;
while ((line = inb.readLine()) != null) {
//System.out.println(line);
String[] ndata = line.split("\t");
word[ct]=ndata[0];
imi[ct]=ndata[1];
ct++;
}
System.out.println("以上 0〜" + (ct-1) + " の " + ct + " 行");
inb.close();
in.close();
}
catch (IOException e) {
System.err.println( fname + " がないのでは?" );
System.err.println( e);
}
//Koukan05.java の交換部分
int n = ct; //word.length だった
for( int i=n-2; i>=0; i-- ){
System.out.println( word[i] + "\t" + i ); //途中経過
for( int j=0; i>=j; j++ ) {
// print(word,i,j);
if( word[j].compareTo(word[j+1]) > 0 ){
String tmp = word[j];
word[j] = word[j+1];
word[j+1] = tmp;
tmp = imi[?];
imi[?] = imi[?];
imi[?] = tmp;
}
// print(word,i,j);
}
}
//結果の報告部分(一部だけ報告)
System.out.println("=-=-=-=-=-=-=-=-=-=");
for (int x = 0; 10>x; x++) {
System.out.println(word[x]+"\t"+imi[x]);
}
System.out.println("=-=-=-=-=");
for (int x = ct-5; ct>x; x++) {
System.out.println(word[x]+"\t"+imi[x]);
}
}//mainの終わり
//printは全部削除
}//classの終わり
コンパイルと実行は次のようにします。
$ javac DicSort01.java $ java DicSort01 ....(途中経過を表示しますが長いので最初の部分は省略)......... absent 10 absence 9 abroad 8 above 7 about 6 able 5 ability 4 a 3 I 2 English 1 Christmas 0 =-=-=-=-=-=-=-=-=-= Christmas クリスマス English 英語,イギリス人,イギリスの,イギリス人の,英語の I 私は a 一つの,ある ability 能力 able できる,有能な about について,およそ,around above の上方へ,の上に,前に abroad 海外へ(で),外国に(で),広く,広まって absence るす,欠席,ないこと =-=-=-=-= yield 産出する,明け渡す,作物がてきてる,屈する you あなた[がた]は(を) young 若い,年下のほうの youth 若さ,青年時代,青年 zero 0,零,零度 $
Christmas, English, I が辞典のabc順と異なります。これは .compareTo() が文字コードの値の差を返すからです。つまり文字コード順なのです。
このままで、.compareTo() を使って二分探索をするのならば、何の問題もありません。Christmas も I も検索できます。もちろん、christmas や i は見つからないことになります。
christmas でも Christmas でも二分探索で検索できるようにするには2つの解決策考えられます。
人間の目で検索するのか、二分探索をするのか、他のアルゴリズムで使うのか、使用方法を考えて並べ替える必要があります。
equalsIgnoreCase() は英語の習慣を救うだけです。日本人にはアルファベットとして同じに見えるフランス語やドイツ語にも異なる文字や習慣があります。まして、アラビア文字やハングル、ひらがな、カタカナなどの問題は一層難しくなります。ひらがなの濁点の処理を例に、文字コード順だけではうまく行かない場合について考えてみましょう。
public class Dakuten01 {
public static void main( String[] args ) {
String[] word = { "じしょ", "じてん", "してん", "しんかい", "しさん", "じこく" };
int n = word.length;
for( int i=n-2; i>=0; i-- ){
for( int j=0; i>=j; j++ ) {
if( word[j].compareTo(word[j+1]) > 0 ){
String tmp = word[j];
word[j] = word[j+1];
word[j+1] = tmp;
}
}
}
for (int x = 0; word.length>x; x++) {
System.out.println(word[x]);
}
}//mainの終わり
}//classの終わり
コンパイルと実行は次のようにします。
$ javac Dakuten01.java $ java Dakuten01 しさん してん しんかい じこく じしょ じてん
二分探索に使うのであれば、これでもまったく問題はありません。
日本人が使う国語辞典の見出しに使うならばこれではいけません。次のようになっている必要があります。これには .compareToIgnoreCase() のような簡単な仕組みはありません。
じこく しさん じしょ してん じてん しんかい
ファイルに出力
英語以外の辞書順