算法练习题15——求两个集合的并集和交集

题目描述:

已知 A 和 B 均是由整型数据组成的集合,使用顺序表表示集合,设计算法求集合A、B 的交集和并集,功能包括输入集合A,输入集合B,求A和B的并集,求A和B的交集。本题中, 线性表的第一个元素位置为1,线性表的最大长度为20。

输入描述:

各个命令以及相关数据的输入格式如下: 
输入集合A:输入A,接下来的一行是要输入的集合元素个数 n ,下面是 n 行数据,每行数据有一个值,代表集合元素值 ;
输入集合B:B,接下来的一行是要输入的集合元素个数 n,下面是 n 行数据,每行数据有一个值;
当输入的命令为 U 时,输出 A 和 B 两个集合的并集;
当输入的命令为 I 时,输出 A 和 B 两个集合的交集;
当输入的命令为 E 时,程序结束。注意,所有的元素均占一行。

输出描述:

当输入的命令为 U 时,输出 A 和 B 两个集合的并集(元素从小到大排序输出) 当输入的命令为 I 时,输出 A 和 B 两个集合的交集(从小到大排序输出)。

注意,所有的元素均占一行!!!

代码示例:

Java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<Integer> a = new ArrayList<>(); // 用于存储集合 A
        ArrayList<Integer> b = new ArrayList<>(); // 用于存储集合 B
        ArrayList<Integer> c = new ArrayList<>(); // 用于存储交集
        ArrayList<Integer> d = new ArrayList<>(); // 用于存储并集

        while (true) {
            char sel = scanner.next().charAt(0); // 读取用户选择的操作

            if (sel == 'A') { // 输入集合 A
                int la = scanner.nextInt(); // 读取集合 A 的大小
                a.clear(); // 清空集合 A 以便重新输入
                for (int i = 0; i < la; i++) {
                    a.add(scanner.nextInt()); // 读取集合 A 的元素
                }
                // 使用传统的 Comparator 对集合 A 进行排序
                a.sort(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer x, Integer y) {
                        return x.compareTo(y); // 按自然顺序升序排序
                    }
                });
            }

            if (sel == 'B') { // 输入集合 B
                int lb = scanner.nextInt(); // 读取集合 B 的大小
                b.clear(); // 清空集合 B 以便重新输入
                for (int i = 0; i < lb; i++) {
                    b.add(scanner.nextInt()); // 读取集合 B 的元素
                }
                // 使用传统的 Comparator 对集合 B 进行排序
                b.sort(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer x, Integer y) {
                        return x.compareTo(y); // 按自然顺序升序排序
                    }
                });
            }

            if (sel == 'U') { // 计算集合 A 和 B 的并集
                d.clear(); // 清空并集集合
                int i = 0, j = 0;
                // 使用双指针法合并两个有序集合 A 和 B
                while (i < a.size() && j < b.size()) {
                    if (a.get(i) < b.get(j)) {
                        d.add(a.get(i++)); // 如果 A[i] 小于 B[j],加入 A[i]
                    } else if (a.get(i) > b.get(j)) {
                        d.add(b.get(j++)); // 如果 A[i] 大于 B[j],加入 B[j]
                    } else {
                        d.add(a.get(i++)); // 如果 A[i] 等于 B[j],加入其中一个并递增 i 和 j
                        j++;
                    }
                }
                // 将剩余的元素加入并集集合 d
                while (i < a.size()) d.add(a.get(i++));
                while (j < b.size()) d.add(b.get(j++));

                // 打印并集结果
                System.out.println("并集: " + Arrays.toString(d.toArray()));
            }

            if (sel == 'I') { // 计算集合 A 和 B 的交集
                c.clear(); // 清空交集集合
                int i = 0, j = 0;
                // 查找两个有序集合 A 和 B 的交集
                while (i < a.size() && j < b.size()) {
                    if (a.get(i) < b.get(j)) {
                        i++; // 如果 A[i] 小于 B[j],递增 i
                    } else if (a.get(i) > b.get(j)) {
                        j++; // 如果 A[i] 大于 B[j],递增 j
                    } else {
                        c.add(a.get(i++)); // 如果 A[i] 等于 B[j],加入交集并递增 i 和 j
                        j++;
                    }
                }

                // 打印交集结果
                System.out.println("交集: " + Arrays.toString(c.toArray()));
            }

            if (sel == 'E') { // 如果输入 'E',退出程序
                break;
            }
        }

        scanner.close(); // 关闭扫描器
    }
}

C

#include<stdio.h>      

int main() {
    int a[20], b[20], c[20], d[40]; // 定义数组 a 和 b 用于存储集合,c 用于存储交集,d 用于存储并集
    int la = 0, lb = 0, lc = 0, ld = 0; // 定义各集合的长度变量
    char sel; // 用于选择操作的字符变量

    while (1) {
        scanf(" %c", &sel); // 读取用户选择的操作

        if (sel == 'A') { // 输入集合 A
            scanf("%d", &la); // 读取集合 A 的大小
            for (int i = 0; i < la; i++) {
                scanf("%d", &a[i]); // 读取集合 A 的元素
            }

            // 对集合 A 进行冒泡排序,确保元素按升序排列
            for (int i = 0; i < la - 1; i++) {
                for (int j = i + 1; j < la; j++) {
                    if (a[i] > a[j]) {
                        int temp = a[i];
                        a[i] = a[j];
                        a[j] = temp;
                    }
                }
            }
        }

        if (sel == 'B') { // 输入集合 B
            scanf("%d", &lb); // 读取集合 B 的大小
            for (int i = 0; i < lb; i++) {
                scanf("%d", &b[i]); // 读取集合 B 的元素
            }

            // 对集合 B 进行冒泡排序,确保元素按升序排列
            for (int i = 0; i < lb - 1; i++) {
                for (int j = i + 1; j < lb; j++) {
                    if (b[i] > b[j]) {
                        int temp = b[i];
                        b[i] = b[j];
                        b[j] = temp;
                    }
                }
            }
        }

        if (sel == 'U') { // 计算集合 A 和 B 的并集
            int i = 0, j = 0;
            // 合并两个有序数组 a 和 b 到数组 d 中
            while (i < la && j < lb) {
                if (a[i] < b[j]) {
                    d[ld++] = a[i++]; // 如果 a[i] 小于 b[j],将 a[i] 加入并集并递增 i
                } else if (a[i] > b[j]) {
                    d[ld++] = b[j++]; // 如果 a[i] 大于 b[j],将 b[j] 加入并集并递增 j
                } else {
                    d[ld++] = a[i++]; // 如果 a[i] 等于 b[j],加入其中一个元素并递增 i 和 j
                    j++;
                }
            }
            // 将剩余的元素加入并集数组 d
            while (i < la) d[ld++] = a[i++];
            while (j < lb) d[ld++] = b[j++];

            // 打印并集结果
            printf("并集: ");
            for (int k = 0; k < ld; k++) {
                printf("%d ", d[k]);
            }
            printf("\n");
        }

        if (sel == 'I') { // 计算集合 A 和 B 的交集
            int i = 0, j = 0;
            // 查找两个有序数组 a 和 b 的交集
            while (i < la && j < lb) {
                if (a[i] < b[j]) {
                    i++; // 如果 a[i] 小于 b[j],递增 i
                } else if (a[i] > b[j]) {
                    j++; // 如果 a[i] 大于 b[j],递增 j
                } else {
                    c[lc++] = a[i++]; // 如果 a[i] 等于 b[j],将该元素加入交集并递增 i 和 j
                    j++;
                }
            }

            // 打印交集结果
            printf("交集: ");
            for (int k = 0; k < lc; k++) {
                printf("%d ", c[k]);
            }
            printf("\n");
        }

        if (sel == 'E') { // 如果输入 'E',退出程序
            return 0;
        }
    }
}

Java小知识:scanner.next() 返回的是一个字符串,如果只输入了一个字符,这个字符串长度为 1,然后用 charAt(0) 来取得这个字符串的第一个字符。

在准备南京大学计算机学院研究生复试的上机试题时,考生需熟悉C++基础和常用算法。推荐使用《南京大学计算机学院研究生复试上机试题解析》这本书,它提供了2009年和2010年的真题内容,帮助考生深入理解题目要和解题思路。 参考资源链接:[南京大学计算机学院研究生复试上机试题解析](https://wenku.csdn.net/doc/5e3fkb326o) 针对2009年的试题,考生需要设计一个名为`IntSet`的类,具体实现步骤如下: 1. 插入整数元素(insert函数):使用cin来接收输入的整数,并将其存储在集合中。考虑到效率问题,可以使用动态数组或链表作为内部存储结构。 2. 比较两个集合是否相等(IsEqual函数):通过遍历两个集合,比较元素是否一一对应相同,实现集合的相等性判断。 3. 计算集合并集(union2函数):创建一个新的集合,遍历两个集合的元素,将不重复的元素加入新集合。 4. 计算集合交集(incorporate2函数):同样创建一个新集合,遍历两个集合的元素,只将共同存在的元素加入新集合。 5. 输出集合中的元素(print函数):遍历集合,并使用cout将元素顺序输出。 在VC++6.0中编译和运行代码时,应确保没有语法错误,并熟悉该开发环境的操作。由于考试时间限制,建议先实现基本功能,再优化代码以提高效率和可读性。 对于2010年的试题,虽然具体内容未知,但考生应保持警惕,可能会涉及更复杂的算法实现。因此,在备考过程中,除了完成上述练习外,还应加强基础算法和数据结构的学习,并在VC++6.0环境下进行充分的编程训练,以应对可能出现的各种编程挑战。 完成上述练习后,继续深入学习可以参考更多关于C++编程和算法的书籍和资源,如《C++ Primer》等,以进一步提高编程水平和理论知识。 参考资源链接:[南京大学计算机学院研究生复试上机试题解析](https://wenku.csdn.net/doc/5e3fkb326o)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值