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

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

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

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

Q&A

解決済

4回答

20866閲覧

単語ごとの出現回数を出現順に表示するには、HashMapとArrayListが必要か

toroleaman

総合スコア95

Java

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

0グッド

1クリップ

投稿2015/09/19 15:19

単語ごとの出現回数を出現順に表示するには、HashMapとArryaListが必要でしょうか。
下記の例よりももっとスマートかつコード量が少なく使用するメモリの量が少ない方法があるはずです。

単語ごとの出現回数をカウントするのは、HashMapでやってみた。
・Integer以外にカウントする方法がありますでしょうか。
・出現順に表示するために出現順は、ArrayListでキー管理しましたが、HashMapで追加されたKeyの順序を覚えていればその順序で表示ができるのですが。

下記のコードをもっと改善できる方いますでしょうか。

String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; String token[] = line.split(" "); HashMap<String,Integer> map = new HashMap<String,Integer>(); ArrayList list = new ArrayList(); for(String key: token){ if(!list.contains(key))list.add(key); if(map.get(key) == null ){ map.put(key,new Integer(1)); }else{ map.put(key,new Integer((int)map.get(key)+1)); } } for (int i = 0; i < list.size(); i++) { StringBuffer a = new StringBuffer(); a.append(list.get(i)); a.append(" "); a.append(map.get(list.get(i))); System.out.println(a); } }

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

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

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

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

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

guest

回答4

0

ベストアンサー

LinkedHashMapを使えば、取り出す時にIteratorを使って登録した順に取り出すことができます。

不要なお世話かも知れませんが、他の箇所も簡略化できるところを変えてます。

なお、これはJava5以降で使えるサンプルです。

lang

1// import java.util.*; 2 3String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; 4String[] tokens = line.split(" "); 5LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>(); 6for (String token : tokens) { 7 if (map.containsKey(token)) { 8 map.put(token, map.get(token) + 1); 9 } else { 10 map.put(token, 1); 11 } 12} 13for (Entry<String, Integer> entry : map.entrySet()) { 14 System.out.printf("%s %d%n", entry.getKey(), entry.getValue()); 15}

Java8でStreamとラムダ式を使うと、さらに簡潔に書けます。

lang

1// import java.util.*; 2// import java.util.stream.*; 3 4String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; 5String[] tokens = line.split(" "); 6Map<String, Integer> map = Stream.of(tokens) 7 .collect(Collectors.toMap(k -> k, v -> 1, (v1, v2) -> v1 + v2, LinkedHashMap::new)); 8map.entrySet().forEach(x -> System.out.printf("%s %d%n", x.getKey(), x.getValue()));

投稿2015/09/19 15:34

編集2015/09/20 04:11
argius

総合スコア9390

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

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

0

TreeSetクラスとComparatorインターフェースを使って実装してみました。
JDK1.6で動作確認しています。

Java

1import java.util.Comparator; 2import java.util.HashMap; 3import java.util.Map; 4import java.util.Map.Entry; 5import java.util.Set; 6import java.util.TreeSet; 7 8public class WordCount { 9 10 public static void main(String[] args) { 11 12 String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; 13 String token[] = line.split(" "); 14 15 Map<String, Integer> map = new HashMap<String, Integer>(); 16 for (String key : token) { 17 if (map.containsKey(key)) { 18 map.put(key, map.get(key) + 1); 19 } else { 20 map.put(key, 1); 21 } 22 } 23 24 // 単語ごとの出現回数を表示 25 for (Map.Entry<String, Integer> entry : map.entrySet()) { 26 System.out.println(entry.getKey() + " " + entry.getValue()); 27 } 28 29 System.out.println(); 30 31 Set<Entry<String, Integer>> set = 32 new TreeSet<Entry<String, Integer>>(new CountComparator()); 33 for (Map.Entry<String, Integer> entry : map.entrySet()) { 34 set.add(entry); 35 } 36 37 // 出現回数の多い順に並び替えて表示 38 for (Map.Entry<String, Integer> entry : set) { 39 System.out.println(entry.getKey() + " " + entry.getValue()); 40 } 41 } 42 43 private static class CountComparator implements Comparator<Entry<String, Integer>> { 44 45 @Override 46 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { 47 if (o2.getValue() != o1.getValue()) { 48 return o2.getValue() - o1.getValue(); 49 } 50 return o1.getKey().compareTo(o2.getKey()); 51 } 52 53 } 54} 55
aaa 3 ddd 2 ccc 1 bbb 3 aaa 3 bbb 3 ddd 2 ccc 1

投稿2015/09/27 14:01

KiyoshiMotoki

総合スコア4791

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

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

toroleaman

2015/10/04 06:27

Comparetor使うのと既存のクラス使うのどっちがいいのでしょうか。 生産性をとるか品質をとるか性能をとるか。 目的によって使い分ける必要がありますね。
guest

0

まず、質問文にあったコードを短くしてみました。 (↓ の wordcount() メソッド)
その次に LinkedHashMap だけをつかって書いてみました。
出現回数の更新は if ... else と条件分岐せずに、map.getOrDefault(key, 0) + 1) で済ませています。

java

1import java.util.ArrayList; 2import java.util.HashMap; 3import java.util.LinkedHashMap; 4import java.util.Map.Entry; 5 6public class WordCount { 7 public static void main(String[] args) { 8 final String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; 9 wordcount(line); 10 System.out.println(); 11 wordcount2(line); 12 } 13 14 //質問文のコードを少し短くした。 15 private static void wordcount(String line) { 16 final String token[] = line.split(" "); 17 HashMap<String, Integer> map = new HashMap<String, Integer>(); 18 ArrayList<String> list = new ArrayList<String>(); 19 20 for (String key : token) { 21 if (!list.contains(key)) { 22 list.add(key); 23 } 24 // getOrDefaullt(key, v) は map に key が未登録なら v を返す。 25 map.put(key, map.getOrDefault(key, 0) + 1); 26 } 27 28 for (String key : list) { 29 System.out.printf("%s\t%4d\n", key, map.get(key)); 30 } 31 } 32 33 // LinkedHashMap だけをつかった 34 private static void wordcount2(String line) { 35 final String token[] = line.split(" "); 36 HashMap<String, Integer> map = new LinkedHashMap<String, Integer>(); 37 38 for (String key : token) { 39 map.put(key, map.getOrDefault(key, 0) + 1); 40 } 41 42 for (Entry<String, Integer> entry : map.entrySet()) { 43 System.out.printf("%s\t%4d\n", entry.getKey(), entry.getValue()); 44 } 45 } 46}

実行例:

aaa 3 bbb 3 ddd 2 ccc 1 aaa 3 bbb 3 ddd 2 ccc 1

投稿2015/09/19 16:59

katoy

総合スコア22324

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

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

toroleaman

2015/10/04 06:15

getOrDefaultは、知りませんでした。ありがとうございます。
guest

0

配列に入れてソートし,その後単語ごとカウントする方法はどうでしょう?

java

1String line = "aaa bbb ddd bbb aaa aaa ccc ddd bbb"; 2String token[] = line.split(" "); 3Arrays.sort(token); //java.util.Array 4String temp = token[0]; 5int count = 1; 6List<WordCount> list = new ArrayList<WordCount>(); 7for(int i = 1; i < token.length; i++){ 8 if(temp.equals(token[i]){ 9 count++; 10 } else { 11 list.add(new WordCount(temp, count); 12 temp = token[i]; 13 count = 1; 14 } 15} 16Collections.sort(list); 17for(int j = 0; j < list.size(); j++){ 18 System.out.println(list.get(j)); 19}

ここで新たにWordCountというクラスを作成して利用しています.

java

1public class WordCount implements Comparable<WordCount>{ 2 private final String WORD; 3 private final int COUNT; 4 public WordCount(String word, int count){ 5 WORD = word; 6 COUNT = count; 7 } 8 public String toString(){ 9 return WORD + " " + COUNT; 10 } 11 public int compareTo(WordCount other){ 12 return other.COUNT - this.COUNT; 13 } 14}

投稿2015/09/19 15:49

swordone

総合スコア20651

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

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

swordone

2015/09/19 16:01

「出現順」でしたね,これはちょっと間違ったようです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問