0

假设您想从迭代中删除一个元素:

a = ['a','b','c','d','e'];
for i = 0 to len(a){
    print a[i];
    if (i==1) a.remove(i);
};

输出为a b d ec缺失。这是一个常见的错误,因为您在数组仍在循环时更改了它。一些解决方法包括在循环后保留要删除的元素列表,并在删除后更新索引。你如何处理这个问题?

4

3 回答 3

1

最明显的方法是从数组的末尾迭代到开头:

a = ['a','b','c','d','e'];
for i = len(a)-1 downto 0 {
    print a[i];
    if (i==1) a.remove(i);
};

许多语言都有迭代器,通过告诉迭代器进行删除来支持在前向迭代期间删除元素。然而,这并不总是有效(例如,Java 返回的列表的迭代器Arrays.asList不支持删除元素,因为列表不“拥有”支持数组。

如果必须使用索引进行前向迭代,请在删除元素时至少从索引中减去 1。这样你就不会跳过元素。

于 2012-11-27T04:22:53.320 回答
0

这取决于您的迭代器访问(包括循环,在您的示例中从 0 迭代到 5,即使位置 5 到最后可能不再存在)是通过集合中的具体位置,还是通过对下一个元素。

例如,Java 中的迭代器属于抽象类型,因此您可以删除指向的项,然后可靠地继续迭代其余的项。

在像 C 这样的语言中,在遍历数组时,您通常会遇到您描述的困难并冒着编写错误代码的风险。也许最好的通用解决方案是累积要删除的“待删除”集合,然后将它们作为单独的步骤进行处理。只有充分了解集合的内部表示以及迭代的工作原理,才能安全地执行删除操作,然后正确调整迭代器——以及循环的终止条件——以继续迭代。但是,无论如何,如果您正在使用数组,这通常会发生。只是附加调整代码是否比维护“要删除”集的代码更简单的问题。

于 2012-11-27T04:27:08.180 回答
0

您甚至可以通过迭代器在迭代中删除它。


vector::iterator itVec = vectInt.begin();
for ( ; itVec != vectInt.end(); )
{
 if (*itVec == 1022) 
  itVec = vectInt.erase(itVect);
 else
  ++itVec;
}

交互器响应知道元素的结尾(而不是通过记录结尾的长度),并释放内存。

于 2012-11-27T04:32:00.313 回答