-1

说,我在代码中有两个向量,如下所示,我想使用 iterators擦除向量“data”中向量“index_to_filter”索引的元素。代码中的虚拟方式只是指出明显的错误。到目前为止,我无法让它工作,也不知道这是否可能是一个擦除删除成语?. 有没有办法并且我想念它?

谢谢。

#include <iostream>
#include <vector>

int main()
{

std::vector<int> data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> index_to_filter{ 1, 5, 8 };

/* needed result data = { 0, 2, 3, 4, 6, 7, 9 }*/

std::vector<int>::iterator iter = index_to_filter.begin();
while (iter != index_to_filter.end())
{
    std::vector<int>::iterator iter_data = data.begin() + *iter;
    iter_data = data.erase(iter_data);
    iter++;
}
/* Throws : vector erase iterator outside range */

for (int i: data)
    std::cout << i << std::endl;

system("pause");
return 0;
}

PS:vector.erase 问题在这里被放弃了数十次,但没有找到这个问题的线索!

PS:不欢迎没有迭代器的解决方案。(没有冒犯的意思 !)

谢谢

4

2 回答 2

5

你的问题很简单:

std::vector<int> index_to_filter{ 1, 5, 8 };

您的意图是从另一个数组中删除元素 #1、#5 和 #8,然后从元素 #1 开始:

Value    0 1 2 3 4 5 6 7 8 9
Index    0 1 2 3 4 5 6 7 8 9
           ^       ^     ^

底线,“索引”线,是向量的索引。最上面的行,“值”行,是向量中那个位置的值。开始时,这两个值是相同的。

插入符号标记您要删除的索引,并从元素 #1 开始。

您忽略的基本差距是,当您从向量中删除一个元素时,您并不完全有一个张开的黑洞,即那个位置的空洞。容器中的所有后续值都会转移。因此,当您删除元素 #1 时,剩余的值会转移:

Value    0 2 3 4 5 6 7 8 9
Index    0 1 2 3 4 5 6 7 8
                   ^     ^

您要删除的下一个元素是元素 #5。不幸的是,向量中那个位置的值不再是 5。它是 6,因为数组已经移动了。您的代码将继续并删除索引位置 #5,其结果如下:

Value    0 2 3 4 5 7 8 9
Index    0 1 2 3 4 5 6 7
                         ^

你已经在这里出轨了。但是现在,您的代码尝试删除不再存在的索引 #8,因为向量现在更短了。一旦您的代码尝试这样做,您就会崩溃。

因此,总而言之:您缺少的是一个简单的事实,即从向量中间删除一个值会将所有后续值向上移动一个位置,以填补删除元素留下的空白,以及您编写的代码未能解释这一点。

最简单的解决方案是从最高索引位置到最低位置删除元素。在您的代码中,您已经index_to_filter按排序顺序进行了排序,因此不是从头到尾迭代index_to_filter,从最低索引到最高索引,而是从最后一个索引index_to_filter到第一个索引向后迭代,因此您的代码尝试删除索引8, 5, 然后 1,这样每次移除元素都不会影响较低的索引位置。

于 2016-05-09T23:00:57.447 回答
1

如果index_to_filter保证已排序,您应该能够以相反的顺序删除元素 - 只要没有删除以前的条目,要过滤的索引仍然正确。

因此,只需在您当前的代码中调用index_to_filter.rbegin()和。index_to_filter.rend()

于 2016-05-09T23:00:47.717 回答