2016-04-04 13 views
0

このプロジェクトに問題があります。基本的な前提は、ユーザーがフレーズを入力することであり、重複する単語やその数が見つかるはずです。Java、ArrayListから要素を削除する

私の問題は、ただ一つの単語を入力するときに、このような ハローハローハローハローハロー

...など、複数回、そのための出力は次のようになりますです。

"There are 2 duplicates of the word "hello" in the phrase you entered." 
"There are 1 duplicates of the word "hello" in the phrase you entered." 

これは、このような状況でのみ発生すると思われます。複数の言葉が入っているランダムなフレーズを入力すると、正しい答えが表示されます。問題は重複した単語を削除することと何回か繰り返されますが、何回も繰り返しますが、私は頭の中で頭を囲むことができません。私はどこにでもプリントラインを追加し、あらゆる種類の方法を繰り返す時代を変えました。私はそれをJavaビジュアライザーで使っていましたが、それでも問題を正確に見つけることはできませんでした。どんな助けでも大歓迎です!

これは私のオンラインJavaコースの課題ですが、それは私の専攻に向かない学習/練習のみです。私は答えを探しているだけではありません。私は私のコードを編集していますが、finalListinputListを追加する前に、私は私が正しい方向に

String previous = ""; 

    for(Iterator<String> i = inputList.iterator(); i.hasNext();) { 
     String current = i.next(); 
     duplicateCounter = 0; 
     for(int j = + 1; j < finalList.size(); j++) { 
      if(current.equalsIgnoreCase(finalList.get(j)) 
        && !current.equals("!") && !current.equals(".") 
        && !current.equals(":") && !current.equals(";") 
        && !current.equals(",") && !current.equals("\"") 
        && !current.equals("?")) { 
       duplicateCounter++; 
       duplicateStr = current.toUpperCase(); 
      } 
      if(current.equals(previous)) { 
       i.remove(); 
      } 

     } 
     if(duplicateCounter > 0) { 
      System.out.printf("There are %s duplicates of the word \"%s\" in the phrase you entered.", duplicateCounter, duplicateStr); 
      System.out.println(); 
     } 
    } 
+2

をそれから項目を除去しながらあなたはArrayListのを反復しています。これにより予期しない動作が発生します。安全な方法は 'Iterator.remove()'です。http://stackoverflow.com/a/223929/4190526 –

+0

アイテムを削除しながら配列を反復したい場合は、配列を作成し、上部に繰り返します。 – annena

答えて

1

あなたの問題は、あなたがアイテムを削除すると、あなたはまだインデックスをインクリメントするということですので、あなたは、次の項目がどうなるかを飛ばします。省略形では、あなたのコードは次のとおりです。

for (int j = i + 1; j < finalList.size(); j++) { 
    String next = finalList.get(i); 
    if (some test on next) 
     finalList.remove(next); 
} 

削除が呼び出された直後に、このように項目を削除すると1位をシャッフルする右にすべての項目が発生するため、「次」の項目は、同じインデックスになりますギャップを埋めるために残った。修正するには、削除した後に、この行を追加する必要があります:あなたの問題を解決するだろう

i--; 

が、しかし、これを行うためのクリーンな方法があります:

String previous = ""; 
for (Iterator<String> i = inputList.iterator(); i.hasNext();) { 
    String current = i.next(); 
    if (current.equals(previous)) { 
     i.remove(); // removes current item 
    } 
    previous = current; 
} 

inputList

は現在、削除されたすべての隣接する重複があります。


すべて重複削除するには:あなたの痛みのような場合は、 "手動" にそれを行う、

List<String> finalList = inputList.stream().distinct().collect(Collectors.toList()); 

を:

Set<String> duplicates = new HashSet<>(); // sets are unique 
for (Iterator<String> i = inputList.iterator(); i.hasNext();) 
    if (!duplicates.add(i.next())) // add returns true if the set changed 
     i.remove(); // removes current item 
+0

上記のようにIteratorを使用すると、iをnextに代入してから、iの代わりにnextを使用します。 inner forループにもIteratorアプローチを使用しますか? – NoobCoderChick

+0

@ sjud9227私は「適切な」コードを編集してより明確にし、全体を表示します。主な違いは 'iterator.remove()'は 'iterator.next()'が返すものを変更しないということです。 – Bohemian

+0

私はまだ少し混乱しています、私の脳は揚げられて7時間私のコンピュータ上でされているごめんなさい。だから私は内部(j)ループの必要はないと言っている? – NoobCoderChick

0

に行くんだか分からない、重複を削除するいくつかの提案に基づいて

public class DuplicateWords { 

public static void main(String[] args) { 

    List<String> inputList = new ArrayList<String>(); 
    List<String> finalList = new ArrayList<String>(); 

    int duplicateCounter; 
    String duplicateStr = ""; 
    Scanner scan = new Scanner(System.in); 

    System.out.println("Enter a sentence to determine duplicate words entered: "); 
    String inputValue = scan.nextLine(); 
    inputValue = inputValue.toLowerCase(); 
    inputList = Arrays.asList(inputValue.split("\\s+")); 
    finalList.addAll(inputList); 


    for(int i = 0; i < inputList.size(); i++) { 
     duplicateCounter = 0; 
     for(int j = i + 1; j < finalList.size(); j++) { 
      if(finalList.get(i).equalsIgnoreCase(finalList.get(j)) 
        && !finalList.get(i).equals("!") && !finalList.get(i).equals(".") 
        && !finalList.get(i).equals(":") && !finalList.get(i).equals(";") 
        && !finalList.get(i).equals(",") && !finalList.get(i).equals("\"") 
        && !finalList.get(i).equals("?")) { 
       duplicateCounter++; 
       duplicateStr = finalList.get(i).toUpperCase(); 
      } 
      if(finalList.get(i).equalsIgnoreCase(finalList.get(j))) { 
       finalList.remove(j); 
      } 

     } 
     if(duplicateCounter > 0) { 
      System.out.printf("There are %s duplicates of the word \"%s\" in the phrase you entered.", duplicateCounter, duplicateStr); 
      System.out.println(); 
     } 
    }  
} 
} 

inputListの商品

+0

Arrays.asListを使用してユーザー入力を分割したため、inputListから何も削除できません。その時点でListは変更できないと思います。 – NoobCoderChick

1

各ワードにMap<String, Integer>を入力して開始します。単語が出現するたびにIntegerを増やしてください。

String inputValue = scan.nextLine().toLowerCase(); 
String[] words = inputValue.split("\\s+"); 
Map<String, Integer> countMap = new HashMap<>(); 
for (String word : words) { 
    Integer current = countMap.get(word); 
    int v = (current == null) ? 1 : current + 1; 
    countMap.put(word, v); 
} 

ような何か、あなたはMapentrySetを反復処理し、カウントが1よりも大きくなるごとにkeyword)を表示することができます。何かのように、あなたのコードで

String msgFormat = "There are %d duplicates of the word \"%s\" in " 
     + "the phrase you entered.%n"; 
for (Map.Entry<String, Integer> entry : countMap.entrySet()) { 
    if (entry.getValue() > 1) { 
     System.out.printf(msgFormat, entry.getValue(), entry.getKey()); 
    } 
} 
+0

同じ複写物ごとに結果を印刷するのと同じ問題はありませんか?意味 "hello"は4つの重複を出力し、次のパスには "hello"という3つの重複があると言います....そのため、リストを繰り返して重複を取り除き始めました。 – NoobCoderChick

+0

@ sjud9227いいえ。各単語はキーなので、 'Map'では** unique **です。 –

+0

よろしいですか?私はマップについて多くのことを理解していないし、今夜はこれを回す必要があります。私は今日マップをスキップして、それを元に戻って練習します。 – NoobCoderChick

関連する問題