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

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

ただいまの
回答率

88.20%

重複した文字列をカウントして、重複した文字列を削除する方法がわかりません

解決済

回答 5

投稿 ・編集

  • 評価
  • クリップ 3
  • VIEW 29K+

itr1214

score 18

将来プログラマーになりたい、専門学校生です。


キーボードから入力
a b c a d

結果
a 2
b 1
c 1
d 1

というようなプログラムを作っているのですが、出現回数のカウントと重複部分の削除のところがよく分かりません。無知な質問かもしれませんが、教えていただければ幸いです。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 5

+3

重複していたら削除と考えるよりも、文字列ごとに登場回数が何回であるかを集計した方が分かりやすいと思います。

Mapという辞書型のデータ構造を使って、文字列に対応する回数を集計します。
Mapに未登録なら初期値として1を登録し、既に登録済みならそのカウントを1増やすようにします。
集計が終わったら、Mapの内容を出力します。

// Java5以降

// import java.util.*;
// import java.util.Map.Entry;

String[] a = {"a", "b", "c", "a", "d"};
Map<String, Integer> m = new HashMap<String, Integer>();
// Java7以降なら new HashMap<>() でOK

for (String s : a) {
    int v;
    if (m.containsKey(s)) {
        // Mapに登録済み
        v = m.get(s) + 1;
    } else {
        // Mapに未登録
        v = 1;
    }
    m.put(s, v);
}
for (Entry<String, Integer> entry : m.entrySet()) {
    System.out.printf("%s %d%n", entry.getKey(), entry.getValue());
}


ラムダを使った方法も考えられると思いますが、難しくなりそうなのでやめておきます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/12/31 15:40

    回答ありがとうございます。僕には無い考え方で、詳しく説明していただきありがとうございます。とても勉強になりました。

    キャンセル

checkベストアンサー

+1

お邪魔します。

いろんな方法があると思うので、こういう方法もありますよ、ぐらいの参考程度で。

Apache commons collectionsに、同じ要素の数を数えるためだけに存在するBugインターフェースというのがあります。
それを使ってやってみました。
(動きを見てもらうためにとりあえずで書いたので色々雑です。
全部mainに書くのもホントはご法度なんだけど;ごめんなさい。。。orz)

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

import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.lang3.StringUtils;

//キーボード入力されたアルファベットを数え上げるプログラム
//動作には右記jarが必要 org.apache.commons.lang3, org.apache.commons.collections4
//アルファベットといいつつ、スペース区切りで入力を判定しているので単語でも数えてしまうのはバグか?!w
public class WordCount {

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

        //ユーザからの入力を取得する
        System.out.println("キーワードを入力:");
        BufferedReader input =
            new BufferedReader (new InputStreamReader(System.in));
        String s = input.readLine();

        //入力値を集計する
        Bag<String> bag = new HashBag<String>();
        for(String each : StringUtils.split(s, " ")) {
            bag.add(each);
        }

        // 結果をコンソールに出力
        for (Object each : bag.uniqueSet()) {
            System.out.println(StringUtils.join(
                    Arrays.asList(Objects.toString(each),
                            Objects.toString(bag.getCount(each))), " "));
        }
    }

}

基本的には他の回答者さんが提示されていたMapによる実装と大きく変わりません。
(自分で書くか、既にある実装に委ねるか、程度の違いだと思ってください)

というか、commonsが無かったら私もMapでやるでしょう。

以上、参考まで。

実行結果のサンプルを張り忘れていました。
キーワードを入力:
a a b c a
a 3 
b 1 
c 1 
こんな感じになります

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/12/31 21:26

    質問者さんはプログラミング初心者さんだと書いてあったので少し。
    なんだか、回答欄を読んでいると検索能力が必須スキルのようになっている気がするので、私なりの考えを述べてみます。
    仕事で新人を教育するような立場にここ数年おかれていてよく思うのは、検索して他人のコードを組み合わせてプログラムを組む人が本当に多いなということです。実際のところ私はそれが本当は残念で。
    本当の技術というのは、無から自分の持っているものを組み合わせて物を作るところにその醍醐味があると思うのですけどね。
    本当に優秀なやつというのは、ネットの無い環境でもjavaのAPIリファレンスだけ渡しとけば試行錯誤してちゃんと動くものを出してくるものです。
    もちろん、調べたり上級者に教えてもらったりすることで、自分では決して発想できなかった効率的なやり方や綺麗な書き方を知ることができる、ということは事実で、大いに調べるべきだし、質問すべきなのですが。
    調べたときに、これを使えばできるというところで終わらずに、そのコードがどうして動作しているのか、そのアルゴリズムと使われているデータ構造を理解して自分のものにしていく、ということと、調べる前に自分の頭で考えて、自分の知りうることだけで動作するものを何とか組み上げようと試行錯誤する、ということが、地味だけれど上達への一番の近道なのではないかと思います。

    キャンセル

  • 2014/12/31 22:23

    回答ありがとうございます。
    新人を教育するような方にアドバイスしていただけるなんて本当にうれしいです。
    まだまだ、出来ないことだらけですが、いろいろ試行錯誤を繰り返して出来ることを増やしていきたいとおもいます!!

    キャンセル

  • 2014/12/31 23:24

    私はそれほど大した技術者ではないのですよ。ただ少し年を取ったというだけです。
    きっとitr1214さんには私よりもっと高いところへいける可能性があるとおもいます。
    正しい努力をして、正しい知識を学んで、大物になってくださいね。
    頑張ってください!!

    キャンセル

+1

以下のページで質問の内容がそのままのっています。
How To Count Duplicated Items In Java List

たいていのことはすでに誰かが行っていて、情報を公開しています。
自分で考えることも重要ですが検索する能力も重要だと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/12/31 13:14

    回答ありがとうございます。貴重なアドバイスをありがとうございます。とても参考になるURLを張ってくださってありがとうございます。

    キャンセル

+1

プログラムの入門段階での知識で、質問文での入力に対して出力を得るだけなら、次のようなコードが考えられます。

// See https://teratail.com/questions/4874

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

public class WordCount {
    public static void main(String[] args) throws Exception {
    // test
    // do_test()

    // ユーザからの入力を取得する
    String str = read_line();
    // 入力値を集計する
    int[] count_info = do_count(str);
    // 結果をコンソールに出力
    print_count_info(count_info);
    }

    private static String read_line() throws IOException {
    System.out.println("キーワードを入力:");
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    String line = input.readLine();
    return(line);
    }
    private static int[] do_count(String str) {
    int[] ans = new int[128];   // 半角文字コード
    for (String s: str.split("")) {
        char ch = s.charAt(0);
        if (ch != ' ') {
        ans[ch]++;
        }
    }
    return(ans);
    }
    private static void print_count_info(int[] count_info) {
    char ch = 0;
    for (int i: count_info) {
        if (i > 0) {
        System.out.format("%c  %d\n", ch, i);
        }
        ch++;
    }
    }
    // private do_test() {
    //  int[] count_info;
    //  print_count_info(do_count("a b c a d"));
    //  print_count_info(do_count("_ aa b  c a d"));
    //  print_count_info(do_count("あ 12 \t \r"));
    //  print_count_info(do_count("a a1 a_1 \t \r"));
    // }
}

// TODO:
//   カウントする単位 (文字、単語 ...) を決めて、それに従って実装すること。
//   空白文字 (tab などの扱いを決めて、それに従って実装すること。
//   日本語文字を扱えるようにすること。
//   Exception の扱いを決めて、それに従って実装すること。
//   STDIN からだけでなく、ファイルの読み込みを実装すること。
//   etc ...
実行例:
java WordCount
キーワードを入力:
a b c a d 
a  2
b  1
c  1
d  1
  
java WordCount
キーワードを入力:
aa 

質問文では、"aa" の入力に対して "a 2" と出力するのか "aa 1" と出力するのかが判明しなかったのでここでは "a 2" と出力するようにしてあります。

日本語文字をあつかうようにしたり、aa 1 と出力するようにしようとすると、上のコードでつかっている固定長さの配列の方法では破綻します。
そのときに java の collection について調べること、それを実際につかって実装できるようになることが必要です。

回避する方法が 他の回答でいろいろと例が示されているわけです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

... 検索する能力...

この場合は "java count frequency" を 検索期間 1 年以内 で検索するとよさそうです。
その検索結果の中から 2 つを紹介します。

http://www.coderslexicon.com/counting-number-frequency-in-java/

http://rosettacode.org/wiki/Letter_frequency
ここには、1つの問題をいろいろな言語で解いた例があります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2014/12/31 15:42

    回答ありがとうございます。まだプログラミング初心者で、おっしゃるとおり、検索する能力が欠如しているんだと思います。こういう風に検索すればいいとアドバイスをしていただき本当にありがとうございます。今後、検索するときの参考にさせてください。

    キャンセル

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

  • ただいまの回答率 88.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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