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

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

ただいまの
回答率

90.47%

  • Java

    14101questions

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

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

解決済

回答 3

投稿 ・編集

  • 評価
  • クリップ 0
  • VIEW 2,120

anna10

score 41

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


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

>りんご
>ごりら
>らっぱ

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

>りんご
>らっぱ
残念でした

>いすたんぶーる
>るびーうぇぽん
残念でした

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

私は、if 文のことを気にするより以前に, プログラムの構造のほうが気になりました。

今回の場合, 条件判定が単純で無い、将来に別の判定ルールが追加されそうな事が予想されるので、判定ロジックは、別メソッドに切り出すのが良いと思います。
そこで次のようにしてみました。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

class Shiritori {

    public static void main(String[] args) throws IOException {
        // BufferedReader&InputStreamReader のインスタンス化
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String prev_str = "";
        while(true) {
            System.out.println(">" + prev_str);
            // キーボードから文字を読み込む。前後の空白文字は削除する。
            String str = br.readLine().trim();

            // 勝負判定をする。
            if (!check_words(prev_str, str)) {
                System.out.println("残念でした");
                break;
            }

            prev_str = str;
            System.out.println("");
        }
    }

    private static boolean check_words(String str1, String str2) {
        // TODO: 長音, 拗音・促音, 拗音・促音, 数字・アルファベット ...
        //        の扱いなどのルールを組み込むことも考慮すること。
        //
        //        See http://ja.wikipedia.org/wiki/しりとり

        // str2 は 2 文字以上でなければならない。
        if (str2.length() <= 1) {
            return false;
        }

        // str2 は "ん" で終わっていてはならない。
        if (str2.endsWith("ん")) {
            return false;
        }

        // 初回のときだけ str1 == '' で呼ばれる。
        // その場合は、これ以降のチェックは不要。
        if (str1.length() == 0) {
            return true;
        }

        // str1 の末尾と str2 の先頭が一致していなければならない。
        if (!str1.endsWith(str2.substring(0, 1))) {
            return false;
        }

        // すべてのチェックをパスした。
        return true;
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/13 21:50

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

    キャンセル

checkベストアンサー

0

お邪魔します。

分岐の部分を以下のように変えれば、それだけでご質問の内容に対しては対応できると思います。
   //if((!(str.endsWith("ん"))) || str.startsWith(msg)){ 
   if(!str.endsWith("ん") 
           && (msg.equals("") || str.startsWith(msg.substring(msg.length()-1)))){
解説ですが、
①msgの中には前回の入力値がすべて入っているので、これとstr.statsWithしても駄目。msgの末尾1文字のみと比較する必要がある。
②最初の1回はmsgがブランク(="")なので、このときは前回入力値の末尾一文字と今回入力値の開始一文字の比較をしない(javaでは左から評価されるので、true || XXXXと記述した場合は必ずtrueになるため右辺=XXXXを評価しません)
②msg内の末尾一文字を取得するため、msgのmsg.length()-1番目から末尾まで(=末尾一文字)を取得して、strの一文字目と比較
という具合です。

※もともと「入力値が"ん"ではないまたは~」となっていましたが、かつの間違いですね。

ただ、この書き方だと一行が長く非常に見づらいので、後で見たときに何をしているのか把握しにくいですね。
それなので、以下のような書き方のほうがよりわかりやすいかもしれません。

package siritori;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Shiritori {

    public static void main(String[] args) throws IOException {

        // BufferedReader&InputStreamReaderのインスタンス化
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String msg = "";

        while (true) {
            System.out.println(">" + msg);
            // キーボードから文字を読み込む
            String str = br.readLine();
            //末尾が"ん"でなく、前回入力値の末尾と今回入力値の一文字目が一致している
            String msg_lastchar = msg.equals("") ? "" : msg.substring(msg.length() - 1);
            if (!str.endsWith("ん") && (str.startsWith(msg_lastchar))) {
                msg = str;
            } else {
                System.out.println("残念でした");
                break;
            }
            System.out.println("");

        }
    }
}


(蛇足)
因みに、もうちょっと色々改造して遊んでみました。
[以下のルールを追加してみました]
①濁音あり・なしどちらでつづけてもOK
②最後が長音("ー")の場合は一つ前の文字からつづける
③過去に1度使った単語はNG

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

class Shiritori {

    private static final String IGNORE_SUFFIX = "ん";
    private static final List<String> DAKUON = Arrays.asList("がぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽ".split(""));
    private static final List<String> SEION = Arrays.asList("かきくけこさしすせそたちつてとはひふへほはひふへほ".split(""));

    public static void main(String[] args) throws IOException {

        // BufferedReader&InputStreamReaderのインスタンス化
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        List<String> msglist = new ArrayList<String>();
        while (true) {

            String msg = msglist.size() > 0 ? msglist.get(msglist.size() - 1) : "";
            System.out.println(">" + msg);

            // キーボードから文字を読み込む
            String str = br.readLine();

            if (!str.endsWith(IGNORE_SUFFIX)
                    && isSafe(msg, str)
                    && !msglist.contains(str)) {
                msglist.add(str);

            } else {
                System.out.println("残念でした");
                break;

            }

            System.out.println("");

        }
    }

    private static boolean isSafe(String last, String current){

        for (Character each : StringUtils.reverse(last).toCharArray()) {
            String item = String.valueOf(each);
            if(StringUtils.equals("ー", item)) {
                continue;
            } else {
                if(current.startsWith(item) || current.startsWith(convertDakuonToSeion(item))) {
                    return true;
                }
                return false;
            }
        }
        return true;
    }

    private static String convertDakuonToSeion(String s) {
        int index = DAKUON.indexOf(s);
        if(index >= 0) {
            return SEION.get(index);
        } else {
            return s;
        }
    }
}
ただ、これだと同じ語でもカタカナとひらがなは違う語とみなされてしまうという問題を抱えています。
(要するに仕様的に不具合かもです。面倒なのでやめましたが。。。)
ちょっと言い方変えればセーフ、みたいな感じです。姑息な小学生を裁けませんね。orz


以上です。
参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/13 21:52

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

    キャンセル

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

同じタグがついた質問を見る

  • Java

    14101questions

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