前言
《算法笔记》 set的常见用法
一、题目描述
题目见:http://codeup.hustoj.com/problem.php?cid=100000597&pid=0
题意:两个整数集合的相似度定义为两集合中相同的元素个数除以总共的元素个数(不重复),任务是求任意两个集合的相似度。
二、需求分析
1.输入分析
每个输入文件一个测试用例。
第一行输入一个正整数N(<=50),接下来输入N个集合,一个集合占一行,且首先给出集合元素个数 M(<104),再给出M个元素。然后一行输入一个正整数K(<=2000),后面输入K行成对的数据,表示需要查询的两个集合(编号从1到2500)。
2.输出分析
对每个查询,以保留一位小数的百分数形式输出集合的相似度,占一行。
3.功能分析
(1)输入集合
(2)求两个集合间的相似度
(3)输出集合的相似度
4.测试数据
输入:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
输出:
50.0%
33.3%
三、概要设计
1.数据结构
集合使用set来保存即可。
2.基本操作
基本操作 | 操作结果 |
---|---|
get_set() | 输入集合 |
calculate_similarity() | 计算两个集合间的相似度 |
print_similarity() | 输出要查询的相似度 |
3.模块及调用图
(1)集合输入模块get_set()
(2)相似度计算模块calculate_similarity()
(3)相似度输出模块print_similarity()
(4)主模块main()
模块调用图:
四、详细设计
1.数据结构
所有集合的保存,使用set数组,大小定义为50。
相似度的保存,使用一维数组保存,数据类型为double,大小定义为2000。
2.各模块
(1)集合输入模块
输入数据规模N,获取N个集合。
(2)相似度计算模块
输入K对整数,计算相应集合的相似度。设两个集合S1、S2,其相似度计算算法如下:
① 思路1,将两个集合合并成一个集合,进行相似度的计算,但是提交的时候错误,百度发现这种方法超时。
② 思路2,在一个集合中查询另一个集合中的元素,计算相同元素的个数。set.find()的返回值是一个迭代器,没找到值为set.end(),遍历完了也没有找到。
实际计算中注意数据类型转换。
(3)相似度输出模块
将相似度按格式输出,“%.1f%%\n”。
五、代码编写
#include <stdio.h>
#include <set>
using namespace std;
const int maxn=60;
const int maxq=2000;
set<int> sets[maxn];
double similarity[maxq];
void get_set(){
int N;
int n,num;
scanf("%d",&N);
for(int i=0;i<N;i++){
scanf("%d",&n);
while(n--){
scanf("%d",&num);
sets[i].insert(num);
}
}
}
int caculate_similarity(){
int K;
int s1,s2;
int Nc,Nt;
set<int> temp_set;
set<int>::iterator it;
scanf("%d",&K);
for(int i=0;i<K;i++){
scanf("%d%d",&s1,&s2);
Nc=0;
for(it=sets[s1-1].begin();it!=sets[s1-1].end();it++)
if(sets[s2-1].find(*it)!=sets[s2-1].end()) Nc++;
Nt=sets[s1-1].size()+sets[s2-1].size()-Nc;
similarity[i]=Nc*1.0*100/Nt;
}
return K;
}
void print_similarity(int n){
for(int i=0;i<n;i++) printf("%.1f%%\n",similarity[i]);
}
int main(){
int n;
get_set();
n=caculate_similarity();
print_similarity(n);
return 0;
}
六、总结
- 百分号的输出前面要再加一个百分号,printf("%%");
- set的find()方法返回的是一个迭代器,找到的话是指向这个元素的迭代器,没找到指向集合的结束位置及set.end()
- 在编写算法时,尽量使用复杂度低的方法。查找find()的复杂度肯定要比插入insert()的复杂度要低,因为插入也要判断元素是否在不在集合内,即也要进行查找。