在std :: set

时间:2017-08-03 12:40:33

标签: c++ c++11 vector stl set

我有两个容器std::setstd::vector,我的任务是返回std::vectorstd::set中存在的元素。实现它的最有效方法是什么? 简单方案: 迭代向量元素并在每个元素上调用set.find,然后在vector.erase调用,如果没有找到。

5 个答案:

答案 0 :(得分:2)

如何寻找每个元素?如果你的矢量没有排序,那么n log(n)

就不可能了
#include <algorithm>

std::vector<int> result;
for(auto&& el: myvector) {
    auto it_found = myset.find(el);
    if(it != myset.end())
        result.push_back(*it_found);
}

现在result包含两者中的所有元素。

PS:Haven没有编译代码,可能会有轻微的错误。

答案 1 :(得分:0)

最短路可能是使用std::set_intersection。但是你应该对矢量进行排序以使其工作:

int main()
{
    std::set<int>    s{1,2,3,4,5,6,7,8};
    std::vector<int> v{7,5,10,9};
    std::sort(v.begin(), v.end()); // should not bother you if vector is small

    std::vector<int> intersection;
    std::set_intersection(s.begin(), s.end(), v.begin(), v.end(), std::back_inserter(intersection));

    for(int n : intersection)
        std::cout << n << ' ';
}

打印:5 7

答案 2 :(得分:0)

根据集合和向量的相对大小,remove_if可能是正确的...

#include <set>
#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
    std::set<int>    s{1,2,3,4,5,6,7,8};
    std::vector<int> v{7,5,10,9};

    v.erase(std::remove_if(v.begin(), v.end(), [&](int e){return s.count(e) == 0;}), v.end());


    for(int n : v)
        std::cout << n << ' ';
}

答案 3 :(得分:0)

您可以使用更多STL:)

#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
#include <iterator>

int main() {
    std::vector<int> v {5, 4, 3, 2, 1};
    std::set<int> s {1, 3, 5};

    v.erase(std::remove_if(v.begin(), v.end(), 
                          [&s](int a) { return s.find(a) == s.end(); }),
            v.end());

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
}

答案 4 :(得分:0)

如果你在复杂性方面寻找最多的 cpu - 有效的方法,有额外的内存和良好的哈希函数,你可以在O中做到这一点(n + m):

std::vector<int> v;
std::set<int> s;
std::unordered_set<int> us{s.cbegin(), s.cend(), s.size()};

v.erase(
    std::remove_if(v.begin(), v.end(),
        [&us] (const int entry) { return us.find(entry) == us.cend(); }),
    v.end());

说明:您迭代set一次(O(m))以准备unordered_set。然后,您遍历vector一次(O(n)),每步执行unordered_set::find(0(1))。它为您提供了O(n + m)的复杂性。

此外,unordered_set的大小等于set的大小和良好的哈希函数有助于减少std::unordered_set::find复杂度的不变部分。

请参阅live example

但请记住,较低的复杂性并不一定意味着在特定情况下执行速度更快(例如,由于额外的分配)。