我需要创建一个方法来删除数组中出现的所有整数。删除整数后,需要将整个列表向下移动,以便用下一个整数填充空格。目前,此方法仅删除给定整数的1次出现。
public void removeAll(int val) {
for (int n = 0; n < list.length; n++) { //goes through each integer
if (list[n] == val) { //checks if the value is what the user enters
for (int j = n; j < list.length - 1; j++) {
list[j] = list[j + 1];
}
list[elements - 1] = 0; //elements is the amount of elements in the array
elements--;
}
}
}
答案 0 :(得分:0)
你是如此亲密:
我还建议不要使用list.length
,而是使用elements
。否则,算法将在val = 0
和列表包含0
时中断。
public void removeAll(int val){
for(int n = 0; n <elements;n++){ // < -- change from list.length to elements
if(list[n] == val){
for (int j = n; j<elements-1;j++){ // < -- change from list.length to elements
list[j]=list[j+1];
}
list[elements-1]=0;
elements--;
n--; // <-- Add this line to not skip over the 'n + 1'th term
}
}
}
问题在于,当您正在迭代集合时,您正在删除后跳过下一个术语。
例如,说val = 2
和list = 1 2 2 3 4 4
:
算法识别并删除值:
1 2 2 3 4 4
^
之后你的数组看起来像这样,下一个要检查的位置是n
,现在它已经增加,以查看集合中的下一个项目。当我的例子中符合删除条件的项目彼此相邻(相邻)时,不难发现这会有问题。
1 2 3 4 4 0
^
为了补偿此事件 - 当您遇到要从集合中删除的项目时,需要像n
那样递减n--;
。这使n
在数组中查看相同的索引,直到该索引不再被要删除的项(也就是与相邻的删除条件匹配的项)占用。
<强>更新强>
如果数组的计数未被用作整个上限且val = 0
包含至少一个0
的数组,会发生什么?
我将继续讨论这个主题并用一个例子说明问题。
允许val = 0
和list = 1 2 0 3 4 4
。像往常一样,算法识别并删除值。
1 2 0 3 4 4
^
现在数组看起来像这样:
1 2 3 4 4 0
^
然而,由于算法仍在迭代集合,直到索引等于list.length
,其仍然是6(它没有像elements
那样递减)。该算法最终将在该集合的索引5处的虚假项目处结束。这就是麻烦开始的地方。
1 2 3 4 4 0
^
索引永远不会移动,因为总是会有另一个相邻的0
,因为我们将它们添加到集合的末尾以表示未使用的索引!最终您的收藏将如下所示:
0 0 0 0 0 0
^
在下面的迭代中,Java会抛出IndexOutOfBoundsException
,因为list[-1] = 0
会发生。
希望有所帮助!