課題2001
コンソールから入力された行を逆順に表示するプログラム LineReversePrint クラスをパッケージ j2.lesson07 に作成しなさい。
このプログラムでは、コンソールからドット「.」一文字のみの入力行が来るまで次々と文字列を入力させ、最後に入力された行から逆順にコンソールに表示する。表示する際は、ドット「.」一文字のみの行はコンソールに表示しない。
つまり、"a", "b", "c", "." と入力すると、
c b a
と出力されるようなプログラムである。
入力部分の擬似コードは次の通りである。擬似コードに従った表示を行うこと。
次を繰り返す print "文字列を入力:" input = コンソール入力 (文字列) input がドット「.」のみであったら繰り返しを終了 input を記憶しておく
上記のプログラムは、j2.lesson07.LineReversePrint クラスの main メソッドに記述すること。
結果の例
このプログラムを実行し、各行に "apple", "orange", "", "grape", "." と順に入力すると、プログラム終了時のコンソール画面は以下のようになっている。
文字列を入力:apple 文字列を入力:orange 文字列を入力: 文字列を入力:grape 文字列を入力:. grape orange apple
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson07 にクラス LineReversePrint を作成
- main メソッドを作成する
- テスト項目「LineReversePrintに対する骨格テスト」をパス
- main メソッドにプログラムを書く
- テスト項目「LineReversePrintに対する機能テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample | 結果の例と同じ入力 |
empty | "." を入力 |
one | "a", "." を入力 |
two | "a", "b", "." を入力 |
three | "a", "b", "c", "." を入力 |
many | 多数の入力を行った後に "." を入力 |
課題2002
英語の文章を日本語らしき文章に変換する簡単な翻訳機 SimpleTranslator クラスをパッケージ j2.lesson07 に作成しなさい。
このプログラムは、英語の単語を日本語の単語に変換できる辞書を持っており、入力された英文の各単語を日本語に変換して表示するだけの簡単な翻訳機である。
例えば、"Time flies like an arrow" という英文を入力すると、下記のように出力される。
英文を入力:Time flies like an arrow 時間は飛ぶまるでひとつの矢
辞書に使うデータは、次のものを使用すること。
入力される単語 | 出力する単語 |
---|---|
time | 時間 |
is | は |
money | お金 |
flies | は飛ぶ |
like | まるで |
a | ひとつの |
an | ひとつの |
arrow | 矢 |
辞書にない単語が入力された場合、次のように元の単語を括弧でくくって表示する。
英文を入力:Time flies like a bullet 時間は飛ぶまるでひとつの(bullet)
上記の場合は、bullet という単語が指定した辞書に登録されていないため、(bullet) と表示している。
次の擬似コードに従った出力をすること。
print "英文を入力:" input = コンソール入力 (文字列) for word = 入力された英単語をスペース区切りで順に if word が辞書に登録されている jword = word を辞書から引いた結果 print jword else print "(" + word + ")"
ただし、入力される英文は大文字でも小文字でも動作するようにすること。例えば、"Time flies like an arrow" と入力した場合と "TIME FLIES LIKE AN ARROW" と入力した場合に出力される日本語の文章が等しくなるように作成すること。
入力される各単語の区切りは常に半角スペース(" ")一文字であると仮定してもよい。また、半角のアルファベットと半角スペース以外の入力に対しては考慮しなくてよい。
上記のプログラムは、j2.lesson07.SimpleTranslator クラスの main メソッドに記述すること。
結果の例
このプログラムを実行し、"Time flies like an arrow" と入力すると、プログラム終了時のコンソール画面は以下のようになっている。
英文を入力:Time flies like an arrow 時間は飛ぶまるでひとつの矢
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson07 にクラス SimpleTranslator を作成
- main メソッドを作成する
- テスト項目「SimpleTranslatorに対する骨格テスト」をパス
- main メソッドにプログラムを書く
- テスト項目「SimpleTranslatorに対する機能テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample1 | 入力 "Time flies like an arrow" |
sample_upper | 入力 "TIME FLIES LIKE AN ARROW" |
sample_lower | 入力 "time flies like an arrow" |
bullet | 入力 "Time flies like a bullet" |
ismoney | 入力 "Time is money" |
moneyflies | 入力 "Money flies" |
課題2003 (optional)
指定した日数後の日付を表示するプログラム DaysLater クラスをパッケージ j2.lesson07 に作成しなさい。
このプログラムは、まずコンソールに日数を入力させ、その値が 0 ならば今日の日付を表示し、正の値 n ならば今日から n 日後の日付を表示する。不の値が入力された場合は "正の値を入力してください" と表示し、プログラムを終了させる。
次の擬似コードに従った出力をすること。
print "日数を入力:" days = コンソール入力 (int) if days が 0 print "今日は" + (年) + "年" + (月) + "月" + (日) + "日", 改行 else if days が正の値 print days + "日後は" + (年) + "年" + (月) + "月" + (日) + "日", 改行 else if days が負の値 print "正の値を入力してください", 改行
表示する部分の (年), (月), (日) には、それぞれ次のような数値を出力すること。
- (年) - 表示すべき日付の 年 を数値 (西暦) で表示
- (月) - 表示すべき日付の 月 を数値 (1~12) で表示
- (日) - 表示すべき日付の 日 を数値 (1~31) で表示
例えば、コンソールに入力された値が 0 で、今日の日付が 2005年1月23日だったとすると、次のように表示される。
日数を入力:0 今日は2005年1月23日
上記のプログラムは、j2.lesson07.DaysLater クラスの main メソッドに記述すること。
結果の例
このプログラムを実行し、"365" と入力すると、プログラム終了時のコンソール画面は以下のようになっている。
日数を入力:365 365日後は2006年11月4日
なお、この資料を作成した時点の日付は 2005年11月4日 である。
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson07 にクラス DaysLater を作成
- main メソッドを作成する
- テスト項目「DaysLaterに対する骨格テスト」をパス
- main メソッドにプログラムを書く
- テスト項目「DaysLaterに対する機能テスト」をパス
ヒント
日付を計算するプログラムを自分で用意してもよいが、できれば API 仕様を調べてそちらを使ってみてほしい。
java.util パッケージに 日付に関するクラスが 2~3 用意されている。そのうち java.util.Date クラスは古い実装で使いにくいため、使用を避けたほうがよい。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
このテストを日付変更の瞬間に実行した際、正しい結果が得られない場合がある。その際は、再度テストを行ってみること。
項目名 | 詳細 |
---|---|
main_M10 | 入力に "-10" |
main_M1 | 入力に "-1" |
main_0 | 入力に "0" |
main_1 | 入力に "1" |
main_2 | 入力に "2" |
main_15 | 入力に "15" |
main_28 | 入力に "28" |
main_29 | 入力に "29" |
main_30 | 入力に "30" |
main_31 | 入力に "31" |
main_32 | 入力に "32" |
main_182 | 入力に "182" |
main_365 | 入力に "365" |
main_1461 | 入力に "1461" |
課題2004 (optional)
二つの java.util.List インスタンスを連結して、一つの List のように扱うためのクラス SyzygyList をパッケージ j2.lesson07 に作成しなさい。
この SyzygyList クラスは List インターフェースを実装するクラスで、「二つの java.util.List インスタンスを連結して、一つの List のように扱う」ことができる。コンストラクタに連結させる 2つの java.util.List インスタンスをとる。コンストラクタの第一引数に渡した List インスタンスが SyzygyList の前半部分で、第二引数に渡した List インスタンスが後半部分となる。
List first = new ArrayList(); List last = new ArrayList(); first.add("a"); first.add("b"); last.add("c"); last.add("d"); System.out.println(first); // -> [a, b] System.out.println(last); // -> [c, d] List syzygy = new SyzygyList(first, last); System.out.println(syzygy); // -> [a, b, c, d]
連結されたリストは get(int) メソッドを呼び出すことによって、連結された元のリストの内容を取得できる。
List first = new ArrayList(); List last = new ArrayList(); first.add("a"); first.add("b"); last.add("c"); last.add("d"); List syzygy = new SyzygyList(first, last); System.out.println(syzygy.get(0)); // -> a System.out.println(syzygy.get(1)); // -> b System.out.println(syzygy.get(2)); // -> c System.out.println(syzygy.get(3)); // -> d
連結されたリストは set(int, Object) メソッドによって変更が可能で、連結されたリストの一部を変更すると、元になったリストの該当部分も同時に変更される。
List first = new ArrayList(); List last = new ArrayList(); first.add("a"); first.add("b"); last.add("c"); last.add("d"); List syzygy = new SyzygyList(first, last); syzygy.set(0, "A"); syzygy.set(3, "D"); System.out.println(first.get(0)); // -> A System.out.println(last.get(1)); // -> D
また、元のリストに対して変更を加えると、連結されたリストの中身も変更される。
List first = new ArrayList(); List last = new ArrayList(); first.add("a"); first.add("b"); last.add("c"); last.add("d"); List syzygy = new SyzygyList(first, last); first.add("first"); last.add("last"); System.out.println(syzygy); // -> [a, b, first, c, d, last]
連結されたリストに対して size() メソッドを呼び出すと、連結元のリストの長さの合計が返される。
SyzygyList は java.util.List インターフェースを実装し (親クラスの誰かが実装しているだけでもよい)、上記のような振る舞いを List の仕様に従ってそれぞれのメソッドに定義すること。
- boolean contains(Object o)
- boolean containsAll(Collection c)
- boolean equals(Object o)
- Object get(int index)
- int hashCode()
- int indexOf(Object o)
- boolean isEmpty()
- Iterator iterator()
- int lastIndexOf(Object o)
- ListIterator listIterator()
- ListIterator listIterator(int index)
- Object set(int index, Object element)
- int size()
- List subList(int fromIndex, int toIndex)
- Object[] toArray()
- Object[] toArray(Object[] a)
- String toString()
下記のメソッドについては、呼び出し時にどのような動作をしてもよい。
- void add(int index, Object element)
- boolean add(Object o)
- boolean addAll(Collection c)
- boolean addAll(int index, Collection c)
- void clear()
- Object remove(int index)
- boolean remove(Object o)
- boolean removeAll(Collection c)
- boolean retainAll(Collection c)
ただし、これまでに例外については解説を行っていないため、例外については考慮しなくてよい。
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson07 にクラス SyzygyList を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- テスト項目「SyzygyListに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「SyzygyListに対する単体テスト」をパス
ヒント
java.util.List の全てのメソッドを実装すると非常に大変である。そのため、このインターフェースの骨格実装を行っているクラスを探すとよい。API 仕様の「関連項目:」という欄が参考になるはずである。
骨格実装を見つければ、メソッドを3つオーバーライドするだけで済む。
テスト
今回はテストプログラムを公開する。単体テストではこれと同様のテストを行う。このテストプログラムの起動方法は、通常の main メソッドを持つクラスと同様である。コメントにある // # は、単体テスト失敗時のメッセージを表している。
このテストケースは、JUnit を用いて記述している。JUnit については、下記の URL にある過去の演習を参考にするとよい。
下記のプログラム内にある assertEquals(Object, Object) メソッドは、「assertEquals(a, b);」と書いたときに、a.equals(b) が実行されて、a と b が同じ内容ならば何もせずに次の行を実行し、a と b の内容が異なればそこでテストを失敗させるメソッドである。また、assertTrue(boolean) や assertFalse(boolean) メソッドは、引数にとられた boolean の値が assert~ で示された値と違う場合はそこでテストを失敗させる。
詳しくは、次のドキュメントを参考にすること。
package j2.lesson07; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import junit.swingui.TestRunner; /** * Test for {@link SyzygyList}. */ public class SyzygyListTest extends TestCase { public static void main(String[] args) { TestRunner.run(SyzygyListTest.class); } /** * Test method for 'java.util.List.equals(Object)' */ public void testEquals() { List ee = new SyzygyList(Collections.EMPTY_LIST, Collections.EMPTY_LIST); List ee2 = new SyzygyList(Collections.EMPTY_LIST, Collections.EMPTY_LIST); assertEquals(ee, ee2); // # equals-0 List ae = new SyzygyList(Collections.singletonList("a"), Collections.EMPTY_LIST); List ea = new SyzygyList(Collections.EMPTY_LIST, Collections.singletonList("a")); assertEquals(ae, ea); // # equals-1 List abe = new SyzygyList(Arrays.asList(new String[]{"a", "b"}), Collections.EMPTY_LIST); List ab = new SyzygyList(Collections.singletonList("a"), Collections.singletonList("b")); List eab = new SyzygyList(Collections.EMPTY_LIST, Arrays.asList(new String[]{"a", "b"})); assertEquals(abe, ab); // # equals-2a assertEquals(ab, eab); // # equals-2b assertEquals(eab, abe); // # equals-2c } /** * Test method for 'java.util.List.iterator()' */ public void testIterator() { List ls = new SyzygyList( Arrays.asList(new String[]{"a", "b", "c"}), Arrays.asList(new String[]{"d", "e"}) ); Iterator iter = ls.iterator(); assertTrue(iter.hasNext()); // # iterator-hasNext-0 assertEquals("a", iter.next()); // # iterator-next-1 assertTrue(iter.hasNext()); // # iterator-hasNext-1 assertEquals("b", iter.next()); // # iterator-next-2 assertTrue(iter.hasNext()); // # iterator-hasNext-2 assertEquals("c", iter.next()); // # iterator-next-3 assertTrue(iter.hasNext()); // # iterator-hasNext-3 assertEquals("d", iter.next()); // # iterator-next-4 assertTrue(iter.hasNext()); // # iterator-hasNext-4 assertEquals("e", iter.next()); // # iterator-next-5 assertFalse(iter.hasNext()); // # iterator-hasNext-5 } /** * Test method for 'java.util.List.get(int)' */ public void testGetInt() { List ls = new SyzygyList( Arrays.asList(new String[]{"a", "b", "c"}), Arrays.asList(new String[]{"d", "e"}) ); assertEquals("a", ls.get(0)); // # get-0 assertEquals("b", ls.get(1)); // # get-1 assertEquals("c", ls.get(2)); // # get-2 assertEquals("d", ls.get(3)); // # get-3 assertEquals("e", ls.get(4)); // # get-4 } /** * Test method for 'java.util.List.set(int, E)' */ public void testSetIntE() { List ls = new SyzygyList( Arrays.asList(new String[]{"a", "b"}), Arrays.asList(new String[]{"c", "d", "e"}) ); assertEquals("a", ls.set(0, "A")); // # set-0 assertEquals("b", ls.set(1, "B")); // # set-1 assertEquals("c", ls.set(2, "C")); // # set-2 assertEquals("d", ls.set(3, "D")); // # set-3 assertEquals("e", ls.set(4, "E")); // # set-4 assertEquals("A", ls.get(0)); // # set-0a assertEquals("B", ls.get(1)); // # set-1a assertEquals("C", ls.get(2)); // # set-2a assertEquals("D", ls.get(3)); // # set-3a assertEquals("E", ls.get(4)); // # set-4a } /** * Test method for 'java.util.List.indexOf(Object)' */ public void testIndexOf() { List ls = new SyzygyList( Arrays.asList(new String[]{"a", "b", "c", "d", "e"}), Arrays.asList(new String[]{"A", "b", "C", "d", "E"}) ); assertEquals(0, ls.indexOf("a")); // # indexOf-0 assertEquals(1, ls.indexOf("b")); // # indexOf-1 assertEquals(2, ls.indexOf("c")); // # indexOf-2 assertEquals(3, ls.indexOf("d")); // # indexOf-3 assertEquals(4, ls.indexOf("e")); // # indexOf-4 assertEquals(5, ls.indexOf("A")); // # indexOf-5 assertEquals(7, ls.indexOf("C")); // # indexOf-6 assertEquals(9, ls.indexOf("E")); // # indexOf-7 } /** * Test method for 'java.util.List.lastIndexOf(Object)' */ public void testLastIndexOf() { List ls = new SyzygyList( Arrays.asList(new String[]{"a", "b", "c", "d", "e"}), Arrays.asList(new String[]{"A", "b", "C", "d", "E"}) ); assertEquals(0, ls.lastIndexOf("a")); // # lastIndexOf-0 assertEquals(2, ls.lastIndexOf("c")); // # lastIndexOf-1 assertEquals(4, ls.lastIndexOf("e")); // # lastIndexOf-2 assertEquals(5, ls.lastIndexOf("A")); // # lastIndexOf-3 assertEquals(6, ls.lastIndexOf("b")); // # lastIndexOf-4 assertEquals(7, ls.lastIndexOf("C")); // # lastIndexOf-5 assertEquals(8, ls.lastIndexOf("d")); // # lastIndexOf-6 assertEquals(9, ls.lastIndexOf("E")); // # lastIndexOf-7 } /** * Test method for 'java.util.List.subList(int, int)' */ public void testSubList() { List head = Arrays.asList(new String[]{"a", "b", "c", "d", "e"}); List tail = Arrays.asList(new String[]{"A", "B", "C", "D", "E"}); List syzygy = new SyzygyList(head, tail); assertEquals(head, syzygy.subList(0, 5)); // # subList-0 assertEquals(tail, syzygy.subList(5, 10)); // # subList-1 assertEquals(Arrays.asList(new String[]{"e", "A"}), syzygy.subList(4, 6)); // # subList-2 } /** * Test method for original method has called 'add(Object)'. */ public void testExternalAdd() { List head = new ArrayList(Arrays.asList(new String[]{"a", "b", "c", "d", "e"})); List tail = new ArrayList(Arrays.asList(new String[]{"A", "B", "C", "D", "E"})); List syzygy = new SyzygyList(head, tail); assertEquals(10, syzygy.size()); // # exadd-0 assertEquals("e", syzygy.get(4)); // # exadd-1 assertEquals("A", syzygy.get(5)); // # exadd-2 head.add("f"); assertEquals(11, syzygy.size()); // # exadd-3 assertEquals("e", syzygy.get(4)); // # exadd-4 assertEquals("f", syzygy.get(5)); // # exadd-5 assertEquals("A", syzygy.get(6)); // # exadd-6 tail.add("F"); assertEquals(12, syzygy.size()); // # exadd-7 assertEquals("E", syzygy.get(10)); // # exadd-8 assertEquals("F", syzygy.get(11)); // # exadd-9 } /** * Test method for original method has called 'remove(int)'. */ public void testExternalRemove() { List head = new ArrayList(Arrays.asList(new String[]{"a", "b", "c", "d", "e"})); List tail = new ArrayList(Arrays.asList(new String[]{"A", "B", "C", "D", "E"})); List syzygy = new SyzygyList(head, tail); assertEquals(10, syzygy.size()); // # exremove-0 assertEquals("e", syzygy.get(4)); // # exremove-1 assertEquals("A", syzygy.get(5)); // # exremove-2 head.remove(3); assertEquals(9, syzygy.size()); // # exremove-3 assertEquals("e", syzygy.get(3)); // # exremove-4 assertEquals("A", syzygy.get(4)); // # exremove-5 tail.remove(0); assertEquals(8, syzygy.size()); // # exremove-6 assertEquals("e", syzygy.get(3)); // # exremove-7 assertEquals("B", syzygy.get(4)); // # exremove-8 } }