我正在尝试从ArrayList中删除重复项。每个元素重复不超过5次。为什么每个副本总是留下2个? (0,0,1,2,2,3,3,4,4,5)。
void quitarRepetidos_lista(ArrayList* lista)
{
eNumero* auxNumero;
eNumero* auxNumero2;
int i,j;
if ( lista != NULL )
{
for (i = 0; i<lista->len(lista); i++)
{
auxNumero = lista->get(lista,i);
for ( j = i+1; j<lista->len(lista); j++ )
{
auxNumero2 = lista->get(lista,j);
if ( numero_compare(auxNumero,auxNumero2) == 0)
{
lista->remove(lista,j);
}
}
}
}
}
int numero_compare(eNumero* numeroAlfa, eNumero* numeroBeta)
{
if ( ((eNumero*)numeroAlfa)->numero >((eNumero*)numeroBeta)->numero )
{
return 1;
}
if ( ((eNumero*)numeroAlfa)->numero < ((eNumero*)numeroBeta)->numero )
{
return -1;
}
return 0;
}
应该说012345
答案 0 :(得分:1)
忽略你的代码在C中不正确的事实(你在调用指针上的方法,例如lista->remove(...)
但是C没有对象)。
这只是猜测,因为我们无法知道ArrayList
类的实现或接口(奇怪地模仿Java SDK中的名称)但是当你做
lista->remove(lista,j);
通常会使j
之后的所有元素都移回一个位置(因为你要删除第j 然后(j + 1)-th 变成第j ,填补空洞。)
j
+---+---+---+---+---+---+
| A | B | C | D | E | F |
+---+---+---+---+---+---+
erase element at j
j
+---+---+---+---+---+
| A | B | D | E | F |
+---+---+---+---+---+
for loop body ends, j is incremented
j
+---+---+---+---+---+
| A | B | D | E | F |
+---+---+---+---+---+
D has been skipped
但是因为你在一个循环中,j
然后由forforrthought增加,有效地跳过一个元素。你应该做点什么:
for ( j = i+1; j < lista->len(); /* no after thought */) {
if (are equal)
lista->remove(j);
else
++j;
如果你刚删除了一个元素,那么你就不会增加j
,因为下一个元素将被置于j
。
答案 1 :(得分:1)
从列表中删除一个元素后,不应该增加j
,否则你最终会跳过下一个元素(它接受刚删除的元素的索引)。
而不是:
if ( numero_compare(auxNumero,auxNumero2) == 0)
{
lista->remove(lista,j);
}
只有在删除元素时才应减少j
:
if ( numero_compare(auxNumero,auxNumero2) == 0)
{
lista->remove(lista,j--);
}
答案 2 :(得分:1)
它崩溃了……
除了Jack和frslm处理的错误之外,ArrayList.c
, function resizeDown()
中还存在错误。
newLen = (pList->reservedSize - pList->size);
AL_INCREMENT
个未使用的元素(请参阅contract()
)时,将缩小列表的保留大小,因此必须将reservedSize
减少AL_INCREMENT
而不是减少pList->size
,后者导致通往小型newLen
的道路。正确:newLen = pList->reservedSize - AL_INCREMENT;
pList->size = newLen;
resizeDown()
仅用于缩小列表的分配空间,而不是从列表中删除元素(contract()
已经做了),因此newLen
必须分配给reservedSize
而不是pList->size
。正确:pList->reservedSize = newLen;