如何比较并获取两个列表中未包含的数值?

huangapple go评论78阅读模式
英文:

How can I compare and get non-Included values in two lists

问题

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

例如,我有这两个列表。

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

然后,如果比较它们,并找出在另一个列表中未包含的值。

像这样:

list1.Compare(list2)
result => {1, 2, 3, 4}

我知道可以使用循环来解决这个问题,

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.push_back(*list1iter);
}

但这是唯一的选择吗?

英文:

I want to compare two lists(stl list) :

for examples, I have these two list.

std::list&lt;int&gt; list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
list1.push_back(4);
list1.push_back(5);

std::list&lt;int&gt; list2;
list2.push_back(5);
list2.push_back(6);
list2.push_back(7);

then, if compared these, and Find not included values list in other list.

like:

list1.Compare(list2)
result =&gt; {1,2,3,4}

I know I made this problem using looping,

std::list&lt;int&gt; result;
for(std::list&lt;int&gt;::iterator list1iter = list1.begin(); list1iter != list1.end(); list1iter++)
{
    bool isInList = false;
    for(std::list&lt;int&gt;::iterator list2iter = list2.begin(); list2iter != list2.end(); list2iter++)
    {
       if(*list1iter == *list2iter)
       {
           isInList = true;
           break;
       }
    }
    if(!isInList)
       result.Add(*list1iter);
}

But this is the only options?

答案1

得分: 2

有(当然)许多不同的选项。在C++中,您可能会使用标准库的某些内容,特别是来自"algorithm"库。请参见这里。您可能特别感兴趣的是"集合操作(对排序范围的操作)"。

您可以在这里找到一个带有易于理解的图形的好描述。

一个可能解决方案的代码示例可能如下所示:

#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;
}

也许您可以从中了解如何完成这个任务。

英文:

There are (of course) many different options. In C++ you would probabaly use something from the standard libray, and here especially from the algorithm library. Please see here. You would be especially interested in the "Set operations (on sorted ranges)".

A nice description with easy to understand graphics you may find here

An code example for a possible solution could be:

#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;list&gt;

int main() {
    
    std::list&lt;int&gt; list1{};
    list1.push_back(1);
    list1.push_back(2);
    list1.push_back(3);
    list1.push_back(4);
    list1.push_back(5);
    
    std::list&lt;int&gt; list2{};
    list2.push_back(5);
    list2.push_back(6);
    list2.push_back(7);
    
    std::list&lt;int&gt; result{};
    
    std::set_difference(list1.begin(),list1.end(), list2.begin(), list2.end(), std::back_inserter(result));
    
    for (const int i : result) std::cout &lt;&lt; i &lt;&lt; &quot;\n&quot;;

    return 0;
}

Maybe you can get the idea on how it could be done.

答案2

得分: 2

有许多方法可以做到这一点。通常认为使用嵌套的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);
英文:

There are many ways to do this. Your idea with a nested for loops is generally considered not an optimal solution since time complexity is O(N^2).

The algorithm can be improved if you had more constraints like if you know that lists are sorted beforehand.

You can use hash maps in order to find the elements from the first lists that are not found in the second one in a more efficient way.

The algorithm's complexity will be O(N) space and O(N) time and works in a generic case - no matter if lists are sorted or not.

The idea is to insert the second list into a hash set and then iterate over the first list to see what items are missing:

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

huangapple
  • 本文由 发表于 2020年1月6日 18:02:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定