7-9 集合相似度 (25分)(c++,set方法)

该博客介绍如何使用C++计算两个整数集合的相似度,定义为两集合共有不相等整数个数与两集合总不相等整数个数的比例。输入包括集合个数、每个集合的元素及其数值,以及需要计算相似度的集合对。输出为相似度的百分比形式。示例展示了具体输入输出格式,并表示代码有待优化。

给定两个整数集合,它们的相似度定义为:N​c​​/N​t​​×100%。其中N​c​​是两个集合都有的不相等整数的个数,N​t​​是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输入格式:

输入第一行给出一个正整数N(≤50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤10​4​​),是集合中元素的个数;然后跟M个[0,10​9​​]区间内的整数。

之后一行给出一个正整数K(≤2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。
输出格式:

对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。
输入样例:

 3
 3 99 87 101
 4 87 101 5 87
 7 99 101 18 5 135 18 99
 2
 1 2
 1 3

输出样例:

50.00%
33.33%

和其他人的不一样,这是统一输入输出的。
当然也有很多待优化的地方,写的很乱,还请大佬多多包涵。

#include<iostream>
#include<iomanip> 
#include<set>
using namespace std;
int main(){
   
   
	set<int> s[10003];
	int 
### 三级标题:L2-005 集合相似度 解题思路与算法析 在解决集合相似度问题时,目标是计算两个集合之间的相似度指标,定义为 $N_c / N_t \times 100\%$,其中 $N_c$ 是两个集合中都存在的不相等整数的个数,而 $N_t$ 是两个集合中总共包含的不同整数的个数[^1]。 #### 数据结构选择 为了高效地处理集合操作,可以使用哈希表或位图来表示每个集合。哈希表适合存储任意范围的整数,并支持快速的查找和插入操作。对于每个输入集合,可以将其存储为一个 `std::unordered_set<int>` 或者类似的结构,以确保元素唯一性并支持高效的交集和并集运算。 #### 计算步骤 1. **读取输入数据**:首先读取所有集合的数据,并将每个集合存储在一个独立的哈希集合中。 2. **统计公共元素数量(Nc)**:对于给定的两个集合,可以通过遍历其中一个集合中的元素,并检查其是否存在于另一个集合中,从而统计出交集中元素的数量。 3. **统计总不同元素数量(Nt)**:通过合并两个集合后去重的方式,可以得到总的不重复元素数量。 4. **计算相似度**:根据公式 $N_c / N_t \times 100\%$,计算出两个集合之间的相似度,并输出结果。 #### 时间复杂度析 假设每个集合平均有 $m$ 个元素,则对于每对集合的比较: - 计算交集的时间复杂度约为 $O(m)$; - 计算并集的时间复杂度约为 $O(m)$; 因此,对于 $k$ 对查询,总时间复杂度为 $O(k \cdot m)$,这在大多数情况下是可以接受的。 #### 示例代码 以下是一个简单的 C++ 实现示例: ```cpp #include <iostream> #include <vector> #include <unordered_set> using namespace std; // 函数用于计算两个集合相似度 double computeSimilarity(const unordered_set<int>& setA, const unordered_set<int>& setB) { int commonCount = 0; // 统计公共元素数量 for (int num : setA) { if (setB.find(num) != setB.end()) { ++commonCount; } } // 计算总不同元素数量 unordered_set<int> unionSet(setA); for (int num : setB) { unionSet.insert(num); } return static_cast<double>(commonCount) / unionSet.size() * 100.0; } int main() { int n; cin >> n; // 输入集合的数量 vector<unordered_set<int>> sets(n); // 读取每个集合的内容 for (int i = 0; i < n; ++i) { int m; cin >> m; // 输入该集合的元素个数 for (int j = 0; j < m; ++j) { int num; cin >> num; sets[i].insert(num); } } int k; cin >> k; // 输入需要查询的集合对数 // 处理每一对查询 for (int i = 0; i < k; ++i) { int idxA, idxB; cin >> idxA >> idxB; // 输入要比较的两个集合索引 --idxA; --idxB; // 转换为从0开始的索引 double similarity = computeSimilarity(sets[idxA], sets[idxB]); cout.precision(2); cout << fixed << similarity << "%" << endl; } return 0; } ``` 这段代码展示了如何使用 `unordered_set` 来处理集合的操作,并且提供了清晰的逻辑来计算相似度。 #### 空间优化建议 如果内存有限,可以考虑使用位图(bit map)来代替哈希集合,但这要求所有的整数值都在一个较小的范围内,以便能够用位图有效地表示这些值。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值