2017-12-22 19 views
1

これは私が予想したよりも難しいです。私はソートされたStringList(単語)のArrayListを持っています。私の仕事は繰り返しを取り除き、各単語のリストを出力し、その後に単語の繰り返し数を出力します。それが私が予想していた以上に複雑だと言っても過言ではない。さまざまなことを試した後、私はHashMapを使って単語(キー)、値(繰り返し)を保存することに決めました。ArrayListで重複する要素とカウントの繰り返しを削除する

これはコードです。 DictionaryはソートされたArrayListであり、そのHashMapは繰り返しです。それは私を+する必要があるにもかかわらず、私は理解していないことを何らかの理由(私は初心者です)については

public void countElements() 
    { 
    String word=dictionary.get(0); 
      int wordCount=1; 
      int count=dictionary.size(); 
      for (int i=0;i<count;i++) 
      { 
       word=dictionary.get(i); 

       for (int j=i+1; j<count;j++) 
       { 


        if(word.equals(dictionary.get(j))) 
        { 

         wordCount=wordCount+1; 
         repetitions.put(word, wordCount);       
         dictionary.remove(j--);        
         count--; 

        } 


       } 
      } 

、私は1でメソッド、変数jデクリメント(j--)dictionary.removeを呼び出した後、 1。私は何が欠けていますか?どのようにこれを正しく行うための任意のアイデアをいただければ幸いです。イテレータを使用するのが最善であることはわかっていますが、それはさらに混乱する可能性があります。 多くのありがとうございます。

+0

イテレータを使用するのは最良ではありません。 –

+1

あなたはそれを思い描いています。リストはソートする必要はありません。各単語について、それが既に地図にあるかどうかをチェックします。 trueの場合、マップの値をインクリメントします。そうでない場合は、値を1にマップに追加します。ストリームでは、1行のコードで行えます。 –

答えて

0

このコードはあなたの目的に役立ちます。現在の辞書にはユニークな単語が含まれ、hashmapには各単語の頻度カウントが含まれます。我々はグループ(Collectors.groupingByを使用して)ここ

final Map<String, Long> countMap = dictionary.stream().collect(
      Collectors.groupingBy(word -> word, LinkedHashMap::new, Collectors.counting())); 
    System.out.println("Counts follow"); 
    System.out.println(countMap); 
    System.out.println("Duplicate-free list follows"); 
    System.out.println(countMap.keySet()); 

得られたマップのキーとして各要素(すなわち、各ワード)を使用してリストの要素、および計数:ストリームを使用

public class newq { 

    public static void main(String[] args) 
    { 
     ArrayList<String> dictionary=new ArrayList<String>(); 
     dictionary.add("hello"); 
     dictionary.add("hello"); 
     dictionary.add("asd"); 
     dictionary.add("qwet"); 
     dictionary.add("qwet"); 
     HashMap<String,Integer> hs=new HashMap<String,Integer>(); 
     int i=0; 
     while(i<dictionary.size()) 
     { 
      String word=dictionary.get(i); 
      if(hs.containsKey(word)) // check if word repeated 
      { 
       hs.put(word, hs.get(word)+1); //if repeated increase the count 
       dictionary.remove(i); // remove the word 

      } 
      else 
      { 
       hs.put(word, 1); //not repeated 
       i++; 
      } 

     } 
     Iterator it = hs.entrySet().iterator(); 
     while(it.hasNext()) 
     { 
      HashMap.Entry pair = (HashMap.Entry)it.next(); 
      System.out.println(pair.getKey() + " = " + pair.getValue()); 
      it.remove(); 
     } 
     for(String word: dictionary) 
     { 
      System.out.println(word); 
     } 
    } 
} 
+1

ああ私。生の型は使用しないでください。そしてイテレータについて知っているので、なぜ最初のループに使うのでしょうか?それはずっと安全ではっきりしています。 Map.merge()を使用する方が簡単です。 –

+0

多くの皆様、お返事いただいた皆様に感謝します。あなたはとても役に立ちました。そして、JB Nizetが言ったように、私はそれを少し考えすぎてしまったと言っています(それにはあまりにも多くの時間を費やしました)。私は理解できない最後のことがまだあります。なぜ私のdictionary.remove(j--)メソッド呼び出しの後、jの値が1減らされます。私はj変数に新しい値を割り当てていないので、それを減らすべきではありませんか?デバッガとprintステートメントを使ってチェックしました。私は間違いなく何かを欠いている。 – Apollonius

1

バージョンこの単語は(Collectors.counting()を使用して)発生します。

外部コレクタ(groupingBy)は、コレクタ(counting)をダウンストリームコレクタとして使用して、1つのワードのすべてのオカレンスを収集(ここではカウント)します。

LinkedHashMapここでは、最初のリストにある単語と同じ順序を維持するために、キーと値のペアが追加された順序が維持されるため、地図を作成するために使用しています。

もう1つ:countMap.keySet()Listではありません。最後にListを取得したい場合は、それはちょうどnew ArrayList(countMap.keySet())です。

+0

しかし、リストから重複は削除されません。 –

+0

おっと、私はそれを忘れてしまった。答えを調整しました。 –

0

「j」を減らしたくない場合は、j-1を使用する必要があります。 j - 、 - j、j ++、++ jを使用すると、変数の値が変更されます。

This linkは、post-enプリインクリメントについての説明と簡単な例があります。

+0

多くの、多くのありがとう。これらの違いは非常に微妙であり、見つけるのは容易ではありません。 – Apollonius

関連する問題