给定两个整数集合,它们的相似度定义为:Nc/Nt×100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后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<algorithm>
#include<set>
#include<vector>
#define MAX 10000
using namespace std;
struct List {
set<int> s;
};
List list[200];
int main()
{
int n, m,temp;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> m;
for (int j = 1; j <= m; j++) {
cin >> temp;
list[i].s.insert(temp);
}
}
int k, a, b;
int nc, nt;
int len = 0;
cin >> k;
for (int i = 0; i < k; i++) {
int flag = -1;
int array[MAX][2] = { 0 };
nc = nt = 0;
len = 0;
cin >> a >> b;
for (auto it = list[a].s.begin(); it != list[a].s.end(); it++) {
array[len][0] = *it;
array[len][1] = 1;
len++;
}
for (auto it = list[b].s.begin(); it != list[b].s.end(); it++) {
for (int j = 0; j < len; j++) {
if (*it == array[j][0]) {
flag = j;
}
}
if (flag != -1) {
array[flag][1]++;
}
else {
array[len][0] = *it;
array[len][1] = 1;
len++;
}
flag = -1;
}
for (int i = 0; i < len; i++) {
if (array[i][1] == 1) {
nt++;
}
else {
nt++;
nc++;
}
}
printf("%.2f", (float)nc * 100 / nt);
cout << "%" << endl;
}
return 0;
}
总结思路:
我发现在输入的时候用set容器,也就是使得每一个集合中的元素只出现一次:
87 99 101
5 87 101
5 18 99 101 135
这样最后把要处理的序列放到一个数组中,记录出现次数,出现次数为2次的记录到nc中,出现次数不为0的记录到nt中即可。
但是题目中的输入的数可以到10的九次方这里我不会处理
别人的代码:比我的简洁多了
#include <iostream>
#include<set>
using namespace std;
set<int> s[60];
int main()
{
int n, k, a, b;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int m, x;
scanf("%d", &m);
while (m--)
{
scanf("%d", &x);
s[i].insert(x);
}
}
scanf("%d", &k);
while (k--)
{
scanf("%d%d", &a, &b);
int jg1 = s[a].size();
int jg2 = s[b].size();
int jg3 = 0;
for (set<int>::iterator it = s[a].begin(); it != s[a].end(); it++)
if (s[b].find(*it) != s[b].end())
jg3++;
printf("%.2f%%\n", jg3 * 1.0 / (jg1 + jg2 - jg3) * 100);
}
return 0;
}
反思:
1.int的取值范围
所以范围在0-10的九次方用int足够了
2.在输入这里因为我不知道有set的数组,所以我把set放在结构体数组中了,增加了代码量
3.不会使用set容器的find方法,我用的二重for循环来寻找值,使得效率降低
4.别人的代码的在计算nt时,运用的交集的运算方法,即a ∪ b = a + b - a ∩ b
也就是这里:
printf("%.2f%%\n", jg3 * 1.0 / (jg1 + jg2 - jg3) * 100);
1.6复习:
#include <iostream>
#include<set>
using namespace std;
int main()
{
int n;
cin >> n;
int temp, k;
set<int> se[60];
for (int i = 1; i <= n; i++) {
cin >> temp;
for (int j = 0; j < temp; j++) {
cin >> k;
se[i].insert(k);
}
}
int m;
cin >> m;
int a, b;
int sum;
for (int i = 0; i < m; i++) {
sum = 0;
cin >> a >> b;
for (auto it = se[a].begin(); it != se[a].end(); it++) {
if (se[b].find(*it) != se[b].end()) {
sum++;
}
}
printf("%.2f%%\n", (float)sum *100/ (se[a].size() + se[b].size() - sum));
}
return 0;
}