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

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

ただいまの
回答率

91.35%

  • Java

    10463questions

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

java 文字の一致がわからない。

解決済

回答 2

投稿 2017/12/01 00:58

  • 評価
  • クリップ 0
  • VIEW 80

akira8

score 10

前提・実現したいこと

赤 1 
青 2 
黄色 3 
上記のように数えた回数を表示したい。

発生している問題・エラーメッセージ

12 
黄色 31 
黄色 2 
黄色 1

該当のソースコード

import java.util.*;


public class Main {
    public static void main(String[] args) {


        Scanner sc = new Scanner(System.in);
        String a = "赤 青 黄色 青 黄色 黄色";
        String[] b = a.split("[ ]");
        int n[] = new int[b.length];


        for(int i=0;i<b.length;i++) {
            for(int j=i;j<b.length;j++) {
                if(b[i].equals(b[j])) {
                    n[i] = n[i] + 1;
                }
            }
        }

        for(int i=0;i<b.length;i++) {
            System.out.println(b[i] + " " + n[i]);
        }
    }
}

試したこと

最後のfor文がいけないことはわかっているのですが、どうしたら「実現したいこと」のような結果になりますか。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

例えばi=1の時のループでj=3の時にifを満たし配列の数値をインクリメントします。この時点で本来ならb[3]にある「青」は用済みなのですが、そのまま残っているためi=3のループで再度カウントされてしまいます。

単純に考えると

先述の通り、一度探したものはもう用済みなので、配列から消してしまうのが簡単でしょうか。
この場合、一致検索する際に「消えているかどうか」の判定も必要になります。

public class Main {
    public static void main(String[] args) {


        Scanner sc = new Scanner(System.in);
        String a = "赤 青 黄色 青 黄色 黄色";
        String[] b = a.split("[ ]");
        int n[] = new int[b.length];


        for(int i = 0; i < b.length; i++) {
            if (b[i] == null) continue;
            n[i] = 1;
            for(int j = i + 1; j < b.length; j++) {
                if(b[i].equals(b[j])) {
                    n[i] = n[i] + 1;
                    b[j] = null;
                }
            }
        }

        for(int i = 0; i < b.length; i++) {
            if (b[i] == null) continue;
            System.out.println(b[i] + " " + n[i]);
        }
    }
}

Mapを使って単純化

Mapを使えば、同じもののカウントを簡単にできます。

public class Main {
    public static void main(String[] args) {


        Scanner sc = new Scanner(System.in);
        String a = "赤 青 黄色 青 黄色 黄色";
        String[] b = a.split("[ ]");
        Map<String, Integer> map = new HashMap<>();

        for(int i = 0; i < b.length; i++) {
            map.merge(b[i], 1, Integer::sum);
        }

        map.forEach((k, v) -> System.out.println(k + " " + v));
    }
}

Streamを使ってさらに短く

public class Main {
    public static void main(String[] args) {

        String a = "赤 青 黄色 青 黄色 黄色";
        String[] b = a.split("[ ]");
        Arrays.stream(b).collect(Collectors.groupingBy(s -> s, Collectors.counting()))
                        .forEach((k, v) -> System.out.println(k + " " + v));
    }
}

投稿 2017/12/01 02:39

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

最後のforがいけないんではなくて、

        for(int i=0;i<b.length;i++) {
            for(int j=i;j<b.length;j++) {
                if(b[i].equals(b[j])) {
                    n[i] = n[i] + 1;
                }
            }
        }


ここの処理がちょっと意味合いが違ってます。
この処理だと自身とそれ以後の一致する数のカウントになります。
これでも出力時にうまいことすればできますが、その場合はこの文字のカウントはすでに表示したから飛ばすとかの処理が必要になります。

が、まあこういうのはさくっと思いつく処理としては、Hashって言う物があるのでこれを利用してカウントするのがいいかと思います。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        for(String val : "赤 青 黄色 青 黄色 黄色".split(" ")) {
            if(map.containsKey(val) == false) {
            }
            map.put(val, map.get(val) + 1);
        }

        for (String key : map.keySet()) {
            System.out.println(key + " " + map.get(key));
        }
    }
}


※あえて一部処理を飛ばしてエラーにしてますので、そこは勉強がてら調べてみてください。

投稿 2017/12/01 02:37

編集 2017/12/01 02:46

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/01 08:07

    最後のログはentrySetでやろうよ。

    キャンセル

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

ただいまの回答率

91.35%

関連した質問

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

  • Java

    10463questions

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