17 集合データ構造とアルゴリズム(2):辞書

17.1 学習目標

17.2 入力プログラムの要素技術

17.2.1 InputTurtle

辞書を作るには、タートル画面から入力を受け付ける部品が必要です。 入力を受け付けるには入力タートルを使います(まだひらがなしか入力できません、すみません)。

17.2.1.1 おうむ返しプログラム(入力タートルバージョン)

このプログラムは、入力された文字をそのまま表示するプログラムです。

リスト 17.2.1.1.1 InputTurtleSample1.java
  1: /*
  2:  * プログラム名:おうむ返しプログラム(入力タートルバージョン) 
  3:  * Created on 2012/01/07
  4:  * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved.
  5:  */
  6: public class InputTurtleSample1 extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new InputTurtleSample1(), args);
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		hide();
 17: 		// 入力ボックス
 18: 		InputTurtle input = new InputTurtle();
 19: 		input.warp(30, 30);
 20: 		// 表示用テキスト
 21: 		TextTurtle text = new TextTurtle("ここに文字が表示されます");
 22: 		text.fontsize(14);
 23: 
 24: 		while (true) {
 25: 			sleep(0.025);// 待つ
 26: 
 27: 			// エンターキーが押されたら
 28: 			if (key() == 10) {
 29: 				text.text(input.text());// 表示用テキストの内容を入力ボックスの内容に変える
 30: 				input.clearText();// 表示用テキストの内容をリセットする
 31: 			}
 32: 
 33: 			update();// 再描画する
 34: 		}
 35: 	}
 36: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、InputTurtleSample1プログラムが実行できます。

キー入力を受けつけ、エンターキーが押されたら、おうむ返しをして、入力ボックスをリセットしています。

17.2.1.2 2つの入力タートルの制御

上記プログラムでは、入力タートルを2つ以上作った場合に、両方のタートルに文字が入力されてしまいます。 これを解決する方法を次のプログラムに示します。このプログラムは、入力タートルを2つを作り、 キー操作によってどちらの入力ボックスを使うか切り替えるプログラムです。

リスト 17.2.1.2.1 InputTurtleSample2.java
  1: /*
  2:  * プログラム名:2つの入力ボックスを切り替えるプログラム 
  3:  * Created on 2012/01/07
  4:  * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved.
  5:  */
  6: public class InputTurtleSample2 extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new InputTurtleSample2(), args);
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		hide();
 17: 
 18: 		// 入力ボックス1
 19: 		InputTurtle input1 = new InputTurtle();
 20: 		input1.warp(30, 30);
 21: 
 22: 		// 入力ボックス2
 23: 		InputTurtle input2 = new InputTurtle();
 24: 		input2.warp(30, 60);
 25: 		input2.setActive(false);
 26: 
 27: 		// 表示用テキスト
 28: 		TextTurtle text = new TextTurtle("ここに文字が表示されます");
 29: 		text.fontsize(10);
 30: 
 31: 		while (true) {
 32: 
 33: 			sleep(0.025);// 待つ
 34: 
 35: 			// エンターキーが押されたら
 36: 			if (key() == 10) {
 37: 				if (input1.isActive()) {
 38: 					text.text(input1.text());
 39: 					input1.clearText();
 40: 				} else if (input2.isActive()) {
 41: 					text.text(input2.text());
 42: 					input2.clearText();
 43: 				}
 44: 			}
 45: 
 46: 			// スペースキーが押されたら
 47: 			if (key() == 32) {
 48: 				if (input1.isActive()) {
 49: 					input1.setActive(false);
 50: 					input2.setActive(true);
 51: 				} else if (input2.isActive()) {
 52: 					input1.setActive(true);
 53: 					input2.setActive(false);
 54: 				}
 55: 			}
 56: 
 57: 			update();// 再描画する
 58: 		}
 59: 	}
 60: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、InputTurtleSample2プログラムが実行できます。

スペースキーが押されたら、フォーカスを切り替えています。

17.2.1.3 InputTurtleの仕様

String text()
入力タートルの内容を取得します
String getText()
text()と同様です
void setActive(boolean active)
入力受付状態を設定します
boolean isActive()
入力受付状態を調べます
void clearText()
入力タートルの内容を消去します
void toJapaneseMode()
日本語入力モードにします。入力できるのはかなのみです。
void toEnglishMode()
英語入力モードにします。入力できるのは小文字のみです。
int fontsize()
フォントサイズを取得します
void fontsize(int size)
フォントサイズを指定します

17.2.2 ButtonTurtle

ButtonTurtleはボタンが押されたことを検知することが出来るオブジェクトです.サンプルプログラムを下記します.

リスト 17.2.2.1 ButtonSample.java
  1: /*
  2:  * プログラム名:ボタンのサンプルプログラム
  3:  * Created on 2012/01/07
  4:  * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved.
  5:  */
  6: public class ButtonSample extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new ButtonSample(), args);
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		hide();
 17: 
 18: 		// ボタンを作る
 19: 		ButtonTurtle helloButton = new ButtonTurtle("押してください!");
 20: 
 21: 		// アニメションループ
 22: 		while (true) {
 23: 			sleep(0.025);
 24: 
 25: 			if (helloButton.isClicked()) {// helloButtonがクリックされたら
 26: 				print("押されました");
 27: 			} else {// 何もクリックされていなかったら
 28: 				// 何もしない
 29: 			}
 30: 
 31: 			update();
 32: 		}
 33: 	}
 34: 
 35: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、ButtonSampleプログラムが実行できます。

ButtonTurtleを使うプログラム実行の注意

ボタンを使ったプログラムをアプレットで実行する際には、必ず、ボタンが表示されている画面を一度クリックしてください。 ボタンが表示されている画面をクリックしないと、ボタンへの入力が受け付けられません。

17.2.2.1 ButtonTurtleの仕様

boolean isClicked()
ボタンがクリックされたか調べます
String text()
ボタンのラベルを文字列型で取得します
String getText()
text()と同様です
void text([ボタンのラベル])
ボタンのラベルを、指定したボタンのラベルに変えます
int fontsize()
ボタンのラベルのフォントサイズを取得します
int fontsize(int size)
ボタンのラベルのフォントサイズを指定します

17.3 辞書のプログラム

このプログラムは、2つのリストを使った絵辞書プログラムです。

1つのリストに、索引となるキーを入れ、もうひとつのリストにはデータを入れています。 ユーザが入力した語が、キーのリストにあるかどうか調べて、 あれば、キーのリストのカーソル位置と同じカーソル位置にあるデータを返します。

リスト 17.3.1 DictionaryApplication.java
  1: /*
  2:  * プログラム名:絵辞書アプリケーション 
  3:  * Created on 2012/01/07
  4:  * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved.
  5:  */
  6: public class DictionaryApplication extends Turtle {
  7: 
  8: 	// 起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new DictionaryApplication(), args);
 11: 	}
 12: 
 13: 	// タートルを動かす処理
 14: 	public void start() {
 15: 
 16: 		hide();
 17: 		window.setSize(700, 500);
 18: 
 19: 		// 入力ボックス
 20: 		InputTurtle input = new InputTurtle();
 21: 		input.toJapaneseMode();
 22: 		input.warpByTopLeft(30, 30);
 23: 
 24: 		// 出力結果
 25: 		ImageTurtle result = new ImageTurtle("notfound.gif");
 26: 		result.size(100, 100);
 27: 		result.warpByTopLeft(30, 60);
 28: 
 29: 		// 辞書の読みを入れておく入れ物
 30: 		ListTurtle<CardTurtle> keys = new ListTurtle<CardTurtle>(true);
 31: 		keys.warpByTopLeft(30, 200);
 32: 		keys.addLast(new CardTurtle("りんご"));
 33: 		keys.addLast(new CardTurtle("いちご"));
 34: 		keys.addLast(new CardTurtle("すいか"));
 35: 		keys.addLast(new CardTurtle("みかん"));
 36: 
 37: 		// 辞書の内容(絵)を入れておく入れ物
 38: 		ListTurtle<ImageTurtle> values = new ListTurtle<ImageTurtle>(true);
 39: 		values.warpByTopLeft(30, 250);
 40: 		values.addLast(new ImageTurtle("apple.gif"));
 41: 		values.addLast(new ImageTurtle("strawberry.gif"));
 42: 		values.addLast(new ImageTurtle("wm.gif"));
 43: 		values.addLast(new ImageTurtle("orange.gif"));
 44: 		values.addLast(new ImageTurtle("notfound.gif"));
 45: 
 46: 		//検索ボタン
 47: 		ButtonTurtle button = new ButtonTurtle("検索!");
 48: 		button.warpByTopLeft(200, 30);
 49: 
 50: 		while (true) {
 51: 			sleep(0.025);// 待つ
 52: 
 53: 			if(button.isClicked()){
 54: 				//検索する
 55: 				String key = input.text();		
 56: 				for (int i = 0; i < keys.getSize(); i++) {// 1つずつ調べる
 57: 					keys.setCursor(i);
 58: 					if (keys.getObjectAtCursor().getText().equals(key)) {// 見つかった
 59: 						values.setCursor(i);
 60: 						result.looks(values.getObjectAtCursor());
 61: 						input.clearText();
 62: 					}
 63: 				}
 64: 			}
 65: 
 66: 			update();// 再描画する
 67: 		}
 68: 	}
 69: 
 70: }

ここ をクリックすると、プログラムをダウンロードできます。

下のボタンを押すと、DictionaryApplicationプログラムが実行できます。

文字列の内容が一致しているか調べる命令

このプログラムでは文字列の内容が一致しているかどうか調べるために、equals命令を使っています。

if (key.getStringAtCursor().equals(searchKey))
				

数値の同値性を調べるためにこれまで利用してきた==命令は、 文字列の同値性を調べるためには使えません(正確には、使えます(コンパイルは通る)が、 内容ではなくオブジェクトが同じかどうか比較してしまうので、誤った結果になる場合があります)。

文字列の内容が一致しているかどうか調べたいときは、A.equals(B)のように、 equals命令を使う必要があります(A,Bはそれぞれ文字列型の変数)。

17.4 練習問題

17.4.1 入力タートルの練習

入力タートルを1つ用意し、スペースキーで入力モード(日本語、英語)を切り替えるプログラムを作ってみよう。

ファイル名は「ChangeMode.java」とすること.

17.4.2 作文さん

このプログラムは、リストに名詞と動詞を保存して、作文するプログラムです。

(リストは、ウインドウの下のほうに隠れています。ウインドウを広げてみてください)

下のボタンを押すと、SakubunApplicationプログラムが実行できます。

実装のヒント

このプログラムでは、入力ボックスをコピーし、コピーしたものをリストに入れています。

以下のプログラムでは、inputという入力タートルの内容をテキストタートルにコピーし、 そのテキストタートルをnounsというリストに入れています。

nouns.addLast(new TextTurtle(input.text()));
						

ファイル名は「Sakubun.java」とすること.

17.4.3 タイピングゲーム

このプログラムは、リストに絵と単語を保存して、タイピングゲームをするプログラムです。

(リストは、ウインドウの下のほうに隠れています。ウインドウを広げてみてください)

下のボタンを押すと、TypingApplicationプログラムが実行できます。

実装のヒント

このプログラムでは、時間を扱います。以下のプログラムは、開始時間をミリ秒で取得するプログラムです。

long型は、int型よりも桁数の大きな数字を扱える型です。

long startTime = System.currentTimeMillis();
						

以下のように、開始時間と終了時間の差(ミリ秒単位)を求め、 それを分単位に変換し、タイピング文字数をかかった時間(分)で割ることで、 タイピング速度を求めることができます。

long endTime = System.currentTimeMillis();
long miliTime = endTime - startTime;//かかった時間(ミリ秒)
double time = (double) miliTime / (double) 1000 / (double) 60;//かかった時間(分)
int speed = (int) (inputCharacterCount / time);
result.text("あなたのタイピング速度は" + speed + "文字/分です.");
					

ファイル名は「Typing.java」とすること.