javaにて、プログラムを作成しています。
以下がソースになります。コンパイルと実行が出来る状態です。
流れとして、まずは
のみが表示され、「入力された文字の末尾が"ん"でなければ」、入力されたmsgに代入して表示します。以降は、「msgの末尾と入力された文字の最初の文字が同じであれば」msgに代入して表示します。
りんご
ごりら
らっぱ
末尾が「ん」であったり、関連性の無い文字が入力された場合はbreakでプログラムを終了します。
りんご
らっぱ
残念でした
いすたんぶーる
るびーうぇぽん
残念でした
※全てログは省略しています。
質問なのですが、最初文字を入力する時は、末尾が「ん」かどうかを調べるだけでいいのですが、以降は「msgに代入してある文字の末尾が、入力された文字の頭と同じ」且つ「末尾が"ん"ではない」という分岐で調べたいので、if文はもう1つ用意した方がいいでしょうか?それとも、if文は最初だけですっきりとプログラムを書く事が出来るでしょうか?どなたか御教授して頂けないでしょうか。よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
私は、if 文のことを気にするより以前に, プログラムの構造のほうが気になりました。
今回の場合, 条件判定が単純で無い、将来に別の判定ルールが追加されそうな事が予想されるので、判定ロジックは、別メソッドに切り出すのが良いと思います。
そこで次のようにしてみました。
lang
1import java.io.BufferedReader; 2import java.io.InputStreamReader; 3import java.io.IOException; 4 5class Shiritori { 6 7 public static void main(String[] args) throws IOException { 8 // BufferedReader&InputStreamReader のインスタンス化 9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 10 11 String prev_str = ""; 12 while(true) { 13 System.out.println(">" + prev_str); 14 // キーボードから文字を読み込む。前後の空白文字は削除する。 15 String str = br.readLine().trim(); 16 17 // 勝負判定をする。 18 if (!check_words(prev_str, str)) { 19 System.out.println("残念でした"); 20 break; 21 } 22 23 prev_str = str; 24 System.out.println(""); 25 } 26 } 27 28 private static boolean check_words(String str1, String str2) { 29 // TODO: 長音, 拗音・促音, 拗音・促音, 数字・アルファベット ... 30 // の扱いなどのルールを組み込むことも考慮すること。 31 // 32 // See http://ja.wikipedia.org/wiki/しりとり 33 34 // str2 は 2 文字以上でなければならない。 35 if (str2.length() <= 1) { 36 return false; 37 } 38 39 // str2 は "ん" で終わっていてはならない。 40 if (str2.endsWith("ん")) { 41 return false; 42 } 43 44 // 初回のときだけ str1 == '' で呼ばれる。 45 // その場合は、これ以降のチェックは不要。 46 if (str1.length() == 0) { 47 return true; 48 } 49 50 // str1 の末尾と str2 の先頭が一致していなければならない。 51 if (!str1.endsWith(str2.substring(0, 1))) { 52 return false; 53 } 54 55 // すべてのチェックをパスした。 56 return true; 57 } 58}
投稿2015/01/13 09:20
総合スコア22324
0
ベストアンサー
お邪魔します。
分岐の部分を以下のように変えれば、それだけでご質問の内容に対しては対応できると思います。
lang
1 //if((!(str.endsWith("ん"))) || str.startsWith(msg)){ 2 if(!str.endsWith("ん") 3 && (msg.equals("") || str.startsWith(msg.substring(msg.length()-1)))){ 4
解説ですが、
①msgの中には前回の入力値がすべて入っているので、これとstr.statsWithしても駄目。msgの末尾1文字のみと比較する必要がある。
②最初の1回はmsgがブランク(="")なので、このときは前回入力値の末尾一文字と今回入力値の開始一文字の比較をしない(javaでは左から評価されるので、true || XXXXと記述した場合は必ずtrueになるため右辺=XXXXを評価しません)
②msg内の末尾一文字を取得するため、msgのmsg.length()-1番目から末尾まで(=末尾一文字)を取得して、strの一文字目と比較
という具合です。
※もともと「入力値が"ん"ではないまたは~」となっていましたが、かつの間違いですね。
ただ、この書き方だと一行が長く非常に見づらいので、後で見たときに何をしているのか把握しにくいですね。
それなので、以下のような書き方のほうがよりわかりやすいかもしれません。
lang
1package siritori; 2 3import java.io.BufferedReader; 4import java.io.IOException; 5import java.io.InputStreamReader; 6 7class Shiritori { 8 9 public static void main(String[] args) throws IOException { 10 11 // BufferedReader&InputStreamReaderのインスタンス化 12 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 13 14 String msg = ""; 15 16 while (true) { 17 System.out.println(">" + msg); 18 // キーボードから文字を読み込む 19 String str = br.readLine(); 20 //末尾が"ん"でなく、前回入力値の末尾と今回入力値の一文字目が一致している 21 String msg_lastchar = msg.equals("") ? "" : msg.substring(msg.length() - 1); 22 if (!str.endsWith("ん") && (str.startsWith(msg_lastchar))) { 23 msg = str; 24 } else { 25 System.out.println("残念でした"); 26 break; 27 } 28 System.out.println(""); 29 30 } 31 } 32}
(蛇足)
因みに、もうちょっと色々改造して遊んでみました。
[以下のルールを追加してみました]
①濁音あり・なしどちらでつづけてもOK
②最後が長音("ー")の場合は一つ前の文字からつづける
③過去に1度使った単語はNG
lang
1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4import java.util.ArrayList; 5import java.util.Arrays; 6import java.util.List; 7 8import org.apache.commons.lang3.StringUtils; 9 10class Shiritori { 11 12 private static final String IGNORE_SUFFIX = "ん"; 13 private static final List<String> DAKUON = Arrays.asList("がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽ".split("")); 14 private static final List<String> SEION = Arrays.asList("かきくけこさしすせそたちつてとはひふへほはひふへほ".split("")); 15 16 public static void main(String[] args) throws IOException { 17 18 // BufferedReader&InputStreamReaderのインスタンス化 19 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 20 21 List<String> msglist = new ArrayList<String>(); 22 while (true) { 23 24 String msg = msglist.size() > 0 ? msglist.get(msglist.size() - 1) : ""; 25 System.out.println(">" + msg); 26 27 // キーボードから文字を読み込む 28 String str = br.readLine(); 29 30 if (!str.endsWith(IGNORE_SUFFIX) 31 && isSafe(msg, str) 32 && !msglist.contains(str)) { 33 msglist.add(str); 34 35 } else { 36 System.out.println("残念でした"); 37 break; 38 39 } 40 41 System.out.println(""); 42 43 } 44 } 45 46 private static boolean isSafe(String last, String current){ 47 48 for (Character each : StringUtils.reverse(last).toCharArray()) { 49 String item = String.valueOf(each); 50 if(StringUtils.equals("ー", item)) { 51 continue; 52 } else { 53 if(current.startsWith(item) || current.startsWith(convertDakuonToSeion(item))) { 54 return true; 55 } 56 return false; 57 } 58 } 59 return true; 60 } 61 62 private static String convertDakuonToSeion(String s) { 63 int index = DAKUON.indexOf(s); 64 if(index >= 0) { 65 return SEION.get(index); 66 } else { 67 return s; 68 } 69 } 70}
ただ、これだと同じ語でもカタカナとひらがなは違う語とみなされてしまうという問題を抱えています。
(要するに仕様的に不具合かもです。面倒なのでやめましたが。。。)
ちょっと言い方変えればセーフ、みたいな感じです。姑息な小学生を裁けませんね。orz
以上です。
参考になれば幸いです。
投稿2015/01/12 11:01
総合スコア540
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/01/13 12:50