Java新手,并在网上看到了这个例子。函数removeZeros应该删除ArrayList中零的所有整数,但由于某些原因,如果它们连续,它不会删除它们。我真的很困惑,因为我不明白为什么它不会严格删除数组中出现的所有0。原因可能很明显,但我看不出来......
public static void main(String args[])
{
List<Integer> a = new ArrayList<Integer>();
a.add(0);
a.add(0);
a.add(4);
System.out.println(a); // prints [0 , 0 , 4]
removeZeros(a);
System.out.println(a); // prints [0 , 4] ?? why not just [4]?
}
// function to remove all zeros from an integer list
public static void removeZeros(List<Integer> nums)
{
for (int i = 0; i < nums.size(); i++)
if (nums.get(i) == 0)
nums.remove(i);
}
任何见解都表示赞赏。
答案 0 :(得分:4)
仅仅是因为索引逻辑不正确。
让我们看一下以下示例:
[1, 0, 0, 4, 5, 0]
我们在索引1
,2
和5
处有零。你的代码开始迭代,索引0
没问题。现在i = 1
我们将使用list.remove(i)
将其从列表中删除。该列表现在看起来像:
[1, 0, 4, 5, 0]
现在注意指数已经改变了!其余的零现在位于索引1
和4
,而不是2
和5
。但是你的循环前进i
,你检查的下一个元素将是i = 2
,因此你会错过位置1
的零。
所以问题是元素的删除影响你的循环的索引逻辑。
一个简单的解决方法是反向执行该程序:
for (int i = nums.size() - 1; i >= 0; i--) {
if (nums.get(i) == 0) {
nums.remove(i);
}
}
因为如果尺寸减小,它不会影响较低的指数。
或者,如果您删除某些内容,请执行此操作,但不要提前i
:
int i = 0;
while (i < nums.size()) {
if (nums.get(i) == 0) {
nums.remove(i);
} else {
i++;
}
}
答案 1 :(得分:1)
这是因为一旦你删除了第一个零,数组现在看起来像:
[0, 4]
然后我们转到索引1,设置为4,因此不会删除。
如用户@Andy Turner所述,您应该以相反的顺序迭代数组
答案 2 :(得分:0)
首次迭代,index
为0,nums
为:
-> 0
0
4
第一个0
已被删除!
第二次迭代,index
为1,nums
为:
0
-> 4
自4!=0
以来,不会删除任何内容,因此您将[0, 4]