L2-005 集合相似度(Java)

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

输入格式:

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

之后一行给出一个正整数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%

解题思路

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

解题过程中遇到的问题

最后还是会存在运行超时问题,暂无找到解决的方法

解题代码

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);

        int n = Integer.parseInt(br.readLine()); // 读取集合的数量
        ArrayList<HashSet<Integer>> sets = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int m = Integer.parseInt(st.nextToken()); // 读取当前集合的元素数量
            HashSet<Integer> set = new HashSet<>();
            for (int j = 0; j < m; j++) {
                int num = Integer.parseInt(st.nextToken()); // 读取元素
                set.add(num);
            }
            sets.add(set);
        }

        int k = Integer.parseInt(br.readLine()); // 读取需要计算相似度的集合对数量
        for (int i = 0; i < k; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken()) - 1; // 转换为索引
            int b = Integer.parseInt(st.nextToken()) - 1;
            HashSet<Integer> setA = sets.get(a);
            HashSet<Integer> setB = sets.get(b);

            int commonElements = 0; // 交集元素数量
            // 计算交集元素数量
            if (setA.size() < setB.size()) {
                for (Integer num : setA) {
                    if (setB.contains(num)) {
                        commonElements++;
                    }
                }
            } else {
                for (Integer num : setB) {
                    if (setA.contains(num)) {
                        commonElements++;
                    }
                }
            }

            int totalElements = setA.size() + setB.size() - commonElements; // 并集的元素数量
            double similarity = 100.0 * commonElements / totalElements; // 相似度

            out.printf("%.2f%%\n", similarity);
        }

        out.flush();
        out.close();
    }
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值