標准庫的<algorithm>頭文件中提供了std::set_difference,std::set_intersection和std::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中有,而v1和v2中交集沒有的元素。
最后的輸出結果如下:
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的結構很簡單,只有兩個字段:group和md5。 然后重載了運算符<方便排序,排序的規則是: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)
上述代碼中使用的幾個方法詳細描述。
