C++求集合的交集差集

标准库的<algorithm>头文件中提供了std::set_difference,std::set_intersectionstd::set_union用来求两个集合的差集,交集和并集。
正好有个需求,需要求在实体类集合A中,但是不再实体类集合B中的元素,可以使用上述方法来实现。

首先,来看下上述几个方法的简单使用。

    std::vector<int> v1{ 1,2,3,4,5,6,7,8 };
    std::vector<int> v2{ 5,  7,  9,10 };
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());

    std::vector<int> v_intersection;

    std::set_intersection(v1.begin(), v1.end(),
        v2.begin(), v2.end(),
        std::back_inserter(v_intersection));
    for (int n : v_intersection)
        std::cout << n << ' ';

    std::vector<int> v_difference;

    // v2 中有,v1中没有
    set_difference(v1.begin(), v1.end(), v_intersection.begin(), v_intersection.end(), inserter(v_difference, v_difference.begin()));

    cout << endl;
    for (int n : v_difference)
        cout << n << " ";
    cout << endl;

声明两个vector<int>set_*方法需要集合是有序的,先调用sort方法排序。后面的使用就比较简单了,调用set_intersection传入两个集合的要进行交操作的区间,back_inserter将两个集合的交集插入到v_intersection中。

调用set_difference查找在集合v1中有,而v1v2中交集没有的元素。

最后的输出结果如下:

5 7
1 2 3 4 6 8

自定义类型

上面的例子使用的是int,在实际应用中,通常需要的自定义的类型。 如下:

struct Item {
    string group;
    string md5;

    Item(const string &g, const string &m) {
        group = g;
        md5 = m;
    }

    bool operator<(const Item &_I) const {
        if (group == _I.group) {
            return md5 < _I.md5;
        }

        return group < _I.group;
    }
};

自定义类型Item的结构很简单,只有两个字段:groupmd5。 然后重载了运算符<方便排序,排序的规则是:group不同,在按照group字段排序; 如果group相同,按照字段md5排序。

测试代码如下:

    Item i1("1", "111");
    Item i2("1", "222");
    Item i3("1", "333");

    Item i4("2", "110");
    Item i5("2", "220");

    vector<Item> list;
    list.push_back(i4);
    list.push_back(i1);
    list.push_back(i2);
    list.push_back(i5);
    list.push_back(i3);


    Item i6("3", "330");
    Item i7("4", "440");

    vector<Item> list1 = { i2, i4, i6, i7 };
    
    sort(list.begin(), list.end());
    sort(list1.begin(), list1.end());

    cout << "list1:###" << endl;
    for (auto i : list)
        cout << "group:" << i.group << " md5:" << i.md5 << endl;

    cout << "list2:###" << endl;
    for(auto i : list1)
        cout << "group:" << i.group << " md5:" << i.md5 << endl;

    vector<Item> item_intersection;
    set_intersection(list.begin(), list.end(), list1.begin(), list1.end(), back_inserter(item_intersection));

    cout << "list1 和 list2 的交集: ###" << endl;
    for(auto i : item_intersection)
        cout << "group:" << i.group << " md5:" << i.md5 << endl;

    vector<Item> item_difference;
    set_difference(list.begin(), list.end(), item_intersection.begin(), item_intersection.end(), back_inserter(item_difference));
    cout << "list1中有,而list2中没有的元素:###" << endl;
    for(auto i : item_difference)
        cout << "group:" << i.group << " md5:" << i.md5 << endl;

最终的输出结果:

总结

并集(http://zh.cppreference.com/w/cpp/algorithm/set_union)
交集(http://zh.cppreference.com/w/cpp/algorithm/set_intersection)
差集(http://zh.cppreference.com/w/cpp/algorithm/set_difference)
inserter(http://zh.cppreference.com/w/cpp/iterator/inserter)
back_inserter(http://zh.cppreference.com/w/cpp/iterator/back_inserter)

上述代码中使用的几个方法详细描述。

posted @ 2018-12-25 11:12  Brook_icv  阅读(16129)  评论(0编辑  收藏  举报