C++ 如何比较和获取两个列表中未包含的值

C++ 如何比较和获取两个列表中未包含的值,c++,C++,我想比较两个列表(stl列表): 例如,我有这两个列表 std::list<int> list1; list1.push_back(1); list1.push_back(2); list1.push_back(3); list1.push_back(4); list1.push_back(5); std::list<int> list2; list2.push_back(5); list2.push_back(6); list2.push_back(7); 我知道我

我想比较两个列表(stl列表):

例如,我有这两个列表

std::list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);

std::list<int> list2;
list2.push_back(5);
list2.push_back(6);
list2.push_back(7);
我知道我是用循环来解决这个问题的

std::list<int> result;
for(std::list<int>::iterator list1iter = list1.begin(); list1iter != list1.end(); list1iter++)
{
    bool isInList = false;
    for(std::list<int>::iterator list2iter = list2.begin(); list2iter != list2.end(); list2iter++)
    {
       if(*list1iter == *list2iter)
       {
           isInList = true;
           break;
       }
    }
    if(!isInList)
       result.Add(*list1iter);
}
std::列表结果;
对于(std::list::迭代器list1iter=list1.begin();list1iter!=list1.end();list1iter++)
{
bool-isInList=false;
对于(std::list::迭代器list2iter=list2.begin();list2iter!=list2.end();list2iter++)
{
如果(*list1iter==*list2iter)
{
isInList=真;
打破
}
}
如果(!isInList)
结果。添加(*list1iter);
}
但这是唯一的选择?

当然有很多不同的选择。在C++中,你可以从标准库中使用一些东西,尤其是从<代码>算法< /代码>库中。请看。您将对“集合操作(在排序范围上)”特别感兴趣

一个很好的描述和易于理解的图形,你可能会发现

可能的解决方案的代码示例可以是:

#include <iostream>
#include <algorithm>
#include <list>

int main() {

    std::list<int> list1{};
    list1.push_back(1);
    list1.push_back(2);
    list1.push_back(3);
    list1.push_back(4);
    list1.push_back(5);

    std::list<int> list2{};
    list2.push_back(5);
    list2.push_back(6);
    list2.push_back(7);

    std::list<int> result{};

    std::set_difference(list1.begin(),list1.end(), list2.begin(), list2.end(), std::back_inserter(result));

    for (const int i : result) std::cout << i << "\n";

    return 0;
}
#包括
#包括
#包括
int main(){
std::list list1{};
列表1.推回(1);
列表1.推回(2);
列表1.推回(3);
列表1.推回(4);
列表1.推回(5);
std::list list2{};
清单2.推回(5);
列表2.推回(6);
列表2.推回(7);
std::列出结果{};
std::set_差异(list1.begin()、list1.end()、list2.begin()、list2.end()、std::back_插入器(结果));

对于(const int i:result)std::cout有很多方法可以做到这一点。您使用嵌套for循环的想法通常被认为不是最佳解决方案,因为时间复杂度为O(N^2)

如果您有更多的约束,例如如果您知道列表是预先排序的,那么算法可以得到改进

您可以使用散列映射以更有效的方式从第一个列表中查找第二个列表中找不到的元素

该算法的复杂度将是O(N)空间和O(N)时间,并在一般情况下工作-无论列表是否排序

其思想是将第二个列表插入到哈希集中,然后迭代第一个列表以查看缺少哪些项:

    std::list<int> result;
    std::unordered_set<int> hash(list2.begin(), list2.end());
    for(const auto el : list1)
        if(hash.find(el) == hash.end()) result.push_back(el);

std::列表结果;
无序集散列(list2.begin(),list2.end());
用于(常数自动el:list1)
if(hash.find(el)=hash.end())result.push_back(el);

.Add
?对于一个
std::list
?另外,两个列表是否都已排序?请检查。@MSalters Oops,我的错误。它不是“Add”,而是“push_back”。这有一个列表需要排序的限制。将不会像一般情况那样工作。请参阅我的答案以获得一般解决方案。
    std::list<int> result;
    std::unordered_set<int> hash(list2.begin(), list2.end());
    for(const auto el : list1)
        if(hash.find(el) == hash.end()) result.push_back(el);