2017-10-26 16 views
0

インデックス0からスキャンされた整数ArrayListの最初の非ゼロ要素の前にすべてのゼロを削除するコードを作成しようとしました。最初の非ゼロ要素の後のゼロの数。 (投稿質問の形式が理想的ではない場合は申し訳ありません。これが私の最初の時間です。)誰が、なぜ?把握することができます 次のコードでは、意図した出力が[2 0 0 0 0 0]だったが、出力は受信でき[2 0 0]Java ArrayList break remove

class Zeroeliminator { 
    public static void main(String args[]) { 
     ArrayList <Integer> arr = new ArrayList <Integer>(); 
     arr.add(0); // A 
     arr.add(2); 
     for (int i = 2; i < 7; i++) 
      arr.add(0); 
     System.out.println(arr.size()); 
     for (int i = 0; i < arr.size(); i++) { 
      if (arr.get(i) != 0) { 
       break; 
      } 
      System.out.println(arr.get(i)); 
      arr.remove(i); 
     } 
     System.out.println(arr.size()); 
     ListIterator <Integer> itr = arr.listIterator(0); 
     while (itr.hasNext()) { 
      System.out.print(itr.next() + " "); 
     } 
     System.out.println(); 
    } 
} 
+1

要素を削除すると、1 ... –

+0

に沿って移動したすべての要素が、最初のゼロでない要素の前後にすべてのゼロを削除しますか? – Lokesh

+1

あなたの問題は、配列を反復しながら配列を突然変異させようとしているという事実から来ています(下記のEranの説明を参照してください)。ここに親切な助言があります:それをしないでください。代わりに、削除するはずのアイテムを追跡し、配列の繰り返しを終えた後にそれらをすべて削除してください(Andyの回答を参照)。 –

答えて

0

ました削除された要素の後のArrayList要素のインデックスが減分されるため、要素を削除するときに、iをデクリメントする必要があります。

for(int i = 0; i < arr.size(); i++) 
{ 
    if(arr.get(i) != 0){ 
     break; 
    } 
    System.out.println(arr.get(i)); 
    arr.remove(i); 
    i--; 
} 
+1

は 'ArrayIndexOutOfBoundsException'を生成する可能性がありますが、この例では発生しません。 – Lino

+0

このコードがArrayIndexOutOfBoundsExceptionを引き起こす可能性はありません。 – Eran

+0

脳のおなら、それはそれを引き起こすことはできません – Lino

5

コードの問題は、要素を削除すると、要素の後にあるすべての要素が1つ下にシフトされることです。だから、一回の反復の状態は次のようになります。次の繰り返しで

arr=[0 2 0 0], i = 0 
     // Remove element i 
arr=[2 0 0], i = 0 
     // Increment i 
arr=[2 0 0], i = 1 

、あなたは私= 1をチェックし、そしてあなたは、その値を読んだことがないので、そこに2があったという事実を無視します。

要素を削除するたびにiを減らして修正できます。しかし、あなたはリストプレフィックスを削除しているので、iは一切必要ありません。代わりに、あなただけ使用できます。

while (!arr.isEmpty() && list.get(0) == 0) { 
    arr.remove(0); 
} 

これに対して(より効率的な)よりよいアプローチは、最初の非ゼロ要素を見つけるために、最初のリストをスキャンし、その後1で前の要素を削除することです移動:他のすべての要素が一つによりシフトダウンされなければならないので、ArrayListの前面から1つの要素を取り外し

int i = 0; 
while (i < arr.size() && arr.get(i) == 0) { 
    i++; 
} 
arr.subList(0, i).clear(); 

は、O(サイズ)です。複数の要素を削除することはO(#removed * size)です。

サブリストを使用するアプローチでは、すべてのシフトが1回で行われるため、O(サイズ)です。

+1

迅速な返信をお寄せいただきありがとうございます(別のアプローチでもっとそうです)!うん、私はremove()がすべての連続する要素のインデックスを減少させるのを忘れていました。 –