2016-04-22 11 views
0

現在のイテレータポイントだけでなく、別の要素も削除したい場合はどうすればよいですか?タスクは、いくつかの値を合計したペアを書き出すことです(HashSetセットに格納されます)。アイデア:セットを繰り返し、必要なものを合計した2番目の要素を見つけ出し、書き出し、両方から削除します。つまり、セットが[1,2,3]でint sum = 4の場合、反復して要素1:1を探し、4 - 1 = 3をチェックし、1,3を書き出し、次に{2}だけが残るように、セットから1と3を削除したいと思います。私はもちろんこれを行うことはできません:コレクションの繰り返し - 他の要素の削除

while (itr.hasNext()) { 
    int elem = itr.next(); 
    int toSum = sum - elem; 
    if (set.contains(toSum)) { 
    System.out.println("(" + elem + "," + toSum + ")"); 
    } 
    itr.remove(); 
    set.remove(toSum); 
} 

同時の例外のためです。私はその解決策を見つけました:

while (itr.hasNext()) { 
    HashSet<Integer> notNeeded = new HashSet<Integer>(); 
    int elem = itr.next(); 
    if (notNeeded.contains(elem)) { 
    itr.remove(); 
    } 
    else { 
    int toSum = sum - elem; 
    if (set.contains(toSum)) { 
     System.out.println("(" + elem + "," + toSum + ")"); 
     notNeeded.add(toSum); 
    } 
    itr.remove(); 
    } 
} 

しかし、それはエレガントで効率的(特にスペース効率的)に見えません。これを行うための良い方法はありますか?

+0

あなたが整数を反復しているので、私はコレクションのコピーを作成し、元のを修正しながら... – jgitter

+0

が理由だけで、ネストされたループを使用しないことを反復処理のでしょうか? – Natecat

+0

ありがとうございました。しかし、私はあなたのアプローチが私のものと違っていることを認めていることを認めなければなりません。私は彼らがより充実しているかどうかは分かりません。 – Malvinka

答えて

1

私は、使用された値で2番目のセットを提案します。その後、実際に元のセットから削除するかどうかを決めることができます。それは非破壊、あなたが他の検索のための設定を再利用することができますすることにより

Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6)); 
int target = 7; 

Set<Integer> used = new HashSet<>(); 
for (Integer value1 : set) { 
    if (used.contains(value1)) 
     continue; // already processed 
    Integer value2 = target - value1; 
    if (! value2.equals(value1) && set.contains(value2)) { 
     used.add(value1); 
     used.add(value2); 
     System.out.println("(" + value1 + "," + value2 + ")"); 
    } 
} 
set.removeAll(used); // optional 

private static void listPairs(Set<Integer> set, int target) { 
    System.out.print(target + ": "); 
    Set<Integer> used = new HashSet<>(); 
    for (Integer value1 : set) 
     if (! used.contains(value1)) { 
      Integer value2 = target - value1; 
      if (! value2.equals(value1) && set.contains(value2)) { 
       used.add(value1); 
       used.add(value2); 
       System.out.print("(" + value1 + "," + value2 + ")"); 
      } 
     } 
    System.out.println(); 
} 
public static void main(String[] args) { 
    Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6)); 
    listPairs(set, 7); 
    listPairs(set, 6); 
    listPairs(set, 5); 
} 

OUTPUT

7: (1,6)(2,5)(3,4) 
6: (1,5)(2,4) 
5: (1,4)(2,3) 
+0

あなたのソリューションと私の唯一の違いは、あなたが元のセットを最後まで変更しないということです。私は正しいのですか、何か迷っていますか? – Malvinka

+1

'notNeeded'がループ内で*宣言されているため、コードが機能しないことを除いて、ええ。 – Andreas

+1

また、「6」の合計を検索すると、結果として '(3,3)'に対して守ります。 – Andreas

0

まあ、もちろんあなたはIterator内からSet.remove()を呼び出すことはできません同時に発生する例外があるため、繰り返しを中断して後で削除することができます。

Integer toSumFound = null; 
while (itr.hasNext()) { 
    int elem = itr.next(); 
    int toSum = sum - elem; 
    if (set.contains(toSum)) { 
     toSumFound = toSum; 
     System.out.println("(" + elem + "," + toSum + ")"); 
     itr.remove(); 
     break; 
    } 
} 
set.remove(toSumFound); //Check for nulls if needed 
関連する問題