zoukankan      html  css  js  c++  java
  • 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)

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

  • 相关阅读:
    HTTP content-type及POST提交数据方式
    Spring Kafka
    Spring动态数据源-AbstractRoutingDataSource(实现分库分表)
    HTTP通信安全和Web攻击技术
    HTTP协议
    zookeeper 图形化的客户端工具:ZooInspector
    centos 中v2r客户端配置实例
    查看视频详细信息
    centos7 创建用户
    logstash
  • 原文地址:https://www.cnblogs.com/wangguchangqing/p/10172828.html
Copyright © 2011-2022 走看看