如何判断一个集合是否精确存在于集合的集合中
问题描述
我需要实现一个判断逻辑:给定集合a = {(0,0,0), (0,1,0), (0,0,1)},以及集合b(其元素是多个集合,比如{((0,0,0), (0,1,0), (0,0,1)), ((0,0,0), (0,1,0), (0,0,2)), ...}),要求判断a是否完全作为一个元素存在于b中。注意:如果b里只有包含a的超集(比如((0,0,0), (0,1,0), (0,0,1), (0,0,2))),函数必须返回false,只有当b里存在和a完全一致的集合元素时才返回true。
我尝试用includes(b.begin(), b.end(), a.begin(), a.end())函数,但它只能判断子集关系,满足不了我的需求。以下是我写的示例代码:
#include <iostream> #include <cmath> #include <cstdio> #include <algorithm> #include <vector> #include <set> #include <tuple> using namespace std; int main() { set <tuple<int, int, int>> coord; set <tuple<int, int, int>> testcoord0; set <tuple<int, int, int>> testcoord1; set <tuple<int, int, int>> total_set; tuple <int, int, int> tuple0 = make_tuple(0, 0, 0); tuple <int, int, int> tuple1 = make_tuple(0, 1, 0); tuple <int, int, int> tuple2 = make_tuple(0, 0, 1); tuple <int, int, int> tuple3 = make_tuple(0, 0, 2); tuple <int, int, int> tuple4 = make_tuple(0, 2, 0); tuple <int, int, int> tuple5 = make_tuple(2, 0, 0); coord.insert(tuple0); coord.insert(tuple1); coord.insert(tuple2); testcoord0.insert(tuple0); testcoord0.insert(tuple1); testcoord0.insert(tuple2); testcoord0.insert(tuple3); total_set.insert(testcoord0.begin(), testcoord0.end()); testcoord1.insert(tuple3); testcoord1.insert(tuple4); testcoord1.insert(tuple5); total_set.insert(testcoord1.begin(), testcoord1.end()); if (includes(total_set.begin(), total_set.end(), coord.begin(), coord.end())) { cout<< "it does exists" << endl; } else { cout<< "it does not exists" << endl; } }
解决方案
1. 修正核心数据结构
你的代码里最关键的错误是total_set的类型定义错误:你需要的是集合的集合,但当前定义成了tuple的集合。正确的类型应该是set<set<tuple<int, int, int>>>,这样total_set的每个元素都是一个set<tuple<...>>,和coord的类型完全匹配。
2. 实现精确匹配逻辑
C++中set的==运算符会直接判断两个集合是否完全相等:元素数量相同,且所有元素一一匹配(set是有序容器,内部会自动排序后比较,无需手动处理顺序)。因此只需遍历total_set中的每个元素,检查是否有和coord完全相等的集合即可。
3. 修改后的代码示例
#include <iostream> #include <set> #include <tuple> using namespace std; int main() { // 定义目标集合a set<tuple<int, int, int>> coord; auto tuple0 = make_tuple(0, 0, 0); auto tuple1 = make_tuple(0, 1, 0); auto tuple2 = make_tuple(0, 0, 1); coord.insert(tuple0); coord.insert(tuple1); coord.insert(tuple2); // 定义集合b:元素是多个集合 set<set<tuple<int, int, int>>> total_set; // 加入一个包含a的超集(不会被匹配) set<tuple<int, int, int>> testcoord0; testcoord0.insert(tuple0); testcoord0.insert(tuple1); testcoord0.insert(tuple2); testcoord0.insert(make_tuple(0, 0, 2)); total_set.insert(testcoord0); // 加入一个无关集合 set<tuple<int, int, int>> testcoord1; testcoord1.insert(make_tuple(0, 0, 2)); testcoord1.insert(make_tuple(0, 2, 0)); testcoord1.insert(make_tuple(2, 0, 0)); total_set.insert(testcoord1); // 加入和a完全一致的集合(会被匹配) set<tuple<int, int, int>> testcoord2 = coord; total_set.insert(testcoord2); // 遍历寻找完全匹配的元素 bool exists = false; for (const auto& s : total_set) { if (s == coord) { exists = true; break; } } if (exists) { cout << "it does exist" << endl; } else { cout << "it does not exist" << endl; } return 0; }
代码说明
- 修正
total_set类型后,其结构完全符合你需求中“集合的集合”的定义。 - 通过
==运算符直接比较子集合和目标集合,确保只有完全一致的情况才会返回true,超集不会被误判。 - 遍历逻辑简单直接,符合C++容器的常规使用方式。
内容的提问来源于stack exchange,提问作者Leo Ouyang
相关产品推荐
相关产品推荐

