質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

3536閲覧

プログラムについての質問です

anna10

総合スコア24

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2015/01/12 06:26

javaにて、プログラムを作成しています。
以下がソースになります。コンパイルと実行が出来る状態です。

流れとして、まずは

のみが表示され、「入力された文字の末尾が"ん"でなければ」、入力されたmsgに代入して表示します。以降は、「msgの末尾と入力された文字の最初の文字が同じであれば」msgに代入して表示します。

りんご
ごりら
らっぱ

末尾が「ん」であったり、関連性の無い文字が入力された場合はbreakでプログラムを終了します。

りんご
らっぱ

残念でした

いすたんぶーる
るびーうぇぽん

残念でした

※全てログは省略しています。

質問なのですが、最初文字を入力する時は、末尾が「ん」かどうかを調べるだけでいいのですが、以降は「msgに代入してある文字の末尾が、入力された文字の頭と同じ」且つ「末尾が"ん"ではない」という分岐で調べたいので、if文はもう1つ用意した方がいいでしょうか?それとも、if文は最初だけですっきりとプログラムを書く事が出来るでしょうか?どなたか御教授して頂けないでしょうか。よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anna10

2015/01/13 12:50

回答誠にありがとう御座います。別メソッドで判定する、というのは今回に至っては全く考えていませんでした。重ねて感謝申し上げます。
guest

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

ShinpeiYamamoto

総合スコア540

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anna10

2015/01/13 12:52

回答誠にありがとう御座います。解説まで入れて下さって助かります。自分でしていた時に、endsWithやstratsWithを使うとエクリプスが頑としてエラーを出し続けるので、subStringで切り出すのかな?とは思っていたのですが。大変助かりました。
guest

0

最初の入力だけループ外でやるのはどうでしょう

投稿2015/01/12 08:53

margalet

総合スコア90

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問