繁体   English   中英

从C ++中另一个向量中包含的另一个向量中删除所有元素?

[英]Removing all elements from one vector that are contained in the other in C++?

我有2个向量vcv2我想删除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;
    }
}

正如评论中指出的那样,您的代码段中有两次未定义的行为。 首先,比较两个不引用同一容器的迭代器。 其次,当vc.erase(i)时, vc迭代器和循环变量i无效。

修复此问题是利用<algorithm>标头和常用习惯用法的一个很好的例子,因为手动实现这些事情很容易出错。 你需要的是所谓的擦除 - 删除 - 成语

#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());

根据应用程序的具体情况,也可能适合保持向量排序(或在某个点对它们进行排序),然后使用二进制搜索来检查元素是否存在,哪个元素可以更好地扩展。

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());

如果允许对输入进行排序,则可以使用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));

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM