我有2个向量vc
和v2
,我想从vc
中删除v2.
中包含的所有元素,我尝试通过2个嵌套循环来实现。但是,编译器给出错误:Debug Assertion Failed
。我想问一下为什么会这样,我该如何解决?
预先感谢!
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector <string> vc;
vector <string> v2;
int main()
{
vc.push_back("ala");
vc.push_back("bala");
vc.push_back("test");
vc.push_back("sample");
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
v2.push_back("test");
v2.push_back("bala");
for (auto i = vc.begin(); i != vc.end(); i++) {
for (auto j = v2.begin(); j != v2.end(); j++) {
if (i == j) {
vc.erase(i);
}
}
}
//it should print only ala and sample after the removal process, but it gives
//debug assertion error
for (int i = 0; i < vc.size(); i++) {
cout << vc[i] << endl;
}
}
答案 0 :(得分:4)
正如评论中指出的那样,您的代码段中有两次未定义的行为。首先,比较两个不引用同一容器的迭代器。其次,vc
迭代器和循环变量i
在调用vc.erase(i)
时无效。
修复这是利用<algorithm>
标头和常见用法的一个很好的例子,因为手动实现此类操作容易出错。您需要的是所谓的erase-remove-idiom:
#include <algorithm>
auto isInV2 = [&v2](const auto& element){
return std::find(v2.cbegin(), v2.cend(), element) != v2.cend(); };
vc.erase(std::remove_if(vc.begin(), vc.end(), isInV2), vc.end());
根据您的应用程序的情况,也可能适合对向量进行排序(或在某些时候对它们进行排序),然后使用二进制搜索来检查是否存在某个元素,该元素在较大的序列中可更好地缩放。 / p>
auto isInV2LogN = [&v2](const auto& element){
return std::binary_search(v2.cbegin(), v2.cend(), element); };
// Important: v2 must be sorted, otherwise std::binary_search doesn't work:
std::sort(v2.begin(), v2.end());
vc.erase(std::remove_if(vc.begin(), vc.end(), isInV2LogN), vc.end());
答案 1 :(得分:1)
如果允许对输入进行排序,则可以使用std::set_difference
:
std::vector<std::string> vc { "ala", "bala", "test", "sample" };
std::vector<std::string> v2 { "test", "bala" };
std::sort(vc.begin(), vc.end());
std::sort(v2.begin(), v2.end());
std::vector<std::string> res;
std::set_difference(vc.begin(), vc.end(),
v2.begin(), v2.end(),
std::back_inserter(res));