题目要求:
(1)实验目的
通过该实验,让学生复习巩固C语言中的循环结构、循环控制条件、分支结构和数组/链表、函数的调用等有关内容,体会到用数组存储集合时,需要记录集合元素的个数,否则输出结果会出现数据越界现象。
(2)实验内容
通过键盘,分别输入两个数据元素类型为正整数的集合A和B,以负数输入为结束条件,输出两个集合的交、并、差。
(3)实验要求
从程序完善性上考虑,集合元素输入时,要有检查元素重复的功能,每个集合中不允许有重复的元素。集合可以用数组也可以用链表存储。
实现交、并、差运算时,分别把代码写成函数的形式,即实现交运算的函数,实现并运算的函数,实现差运算的函数,在主函数中分别调用三个函数。
使用菜单形式对应各个操作,应允许用户反复查看结果,想结束程序时,输入负数结束,使其编成一个完整的小软件。菜单参考示例如下:
1---输入集合A和B
2---求集合A交B
3---求集合A并B
4---求集合A-B
退出,输入一个负数!
源代码:
#include<iostream>
using namespace std;
#include <windows.h>
/*要求:
* 集合元素输入时,要有检查元素重复的功能,每个集合中不允许有重复的元素。
* 实现交、并、差运算时,分别把代码写成函数的形式
* 应允许用户反复查看结果,想结束程序时,输入负数结束
*
1---输入集合A和B
2---求集合A交B
3---求集合A并B
4---求集合A-B
0---退出
*
*/
//对程序中常用的数组、数据进行声明并初始化
//arrA、arrB为用户创建的两个集合A、B;arrC、arrD、arrE分别为集合A、B的交集、并集、差集
//lengthA、lengthB、lengthC、lengthD、lengthE分别为对应集合中存储元素的个数
int arrA[100], arrB[100], arrC[100], arrD[200], arrE[100];
int lengthA = 0, lengthB = 0, lengthC = 0, lengthD = 0, lengthE = 0, num = 0, choose = 1;
//显示菜单
void showMenu()
{
cout << "*******************************************" << endl;
cout << "***** 1---输入集合A和B *****" << endl;
cout << "***** 2---求集合A交B *****" << endl;
cout << "***** 3---求集合A并B *****" << endl;
cout << "***** 4---求集合A-B *****" << endl;
cout << "***** 0---退出 *****" << endl;
cout << "*******************************************" << endl;
}
//检查集合中元素是否重复
//如果有重复元素,返回0;如果没有,返回1。
//用于创建集合时判断用户输入的数据是否符合要求
int checkArray(int arr[], int length)
{
int score = 1, i = 0, j = 0;
for (i = 0; i < length; i++)
{
//将后面的元素一次与前面的元素比较
for (j = i + 1; j < length; j++)
{
if (arr[i] == arr[j])
{
//若有重复元素,将score赋值为0,退出循环
score = 0;
break;
}
}
}
return score;
}
//集合的输出
void showArray(int Array1[], int length1)
{
//如该数组长度为0,则该集合必为空集
if (length1 == 0)
{
cout << " 空集!" << endl;
}
else
{
//对不是空集的集合进行遍历,并按照集合的形式输出
cout << "{";
for (int j = 0; j < length1 - 1; j++)
{
cout << Array1[j] << ",";
}
cout << Array1[length1 - 1];
cout << "}";
cout << endl;
}
}
//1.集合的构造
int createArray(int Array[])
{
cout << "请分别输入集合中的元素:" << endl;
int i = 0, k = 0;
//循环结构,将用户输入的值一次存入数组
while (k >= 0)
{
cin >> k;
Array[i] = k;
i++;
}
//记录用户输入的数据个数并返回,便于后续数组的遍历与输出
//输入元素个数为 i-1
return i - 1;
}
//2.集合的交集:arrC[100] lengthC
//Array1、Array2、Array3分别代表:用户创建的集合A、B,集合A、B的交集
//length1、length2、length3分别为:对应集合中存储元素的个数
int Intersection(int Array1[], int length1, int Array2[], int length2, int Array3[], int length3)
{
for (int i = 0; i < length1; i++)
{
for (int j = 0; j < length2; j++)
{
//将集合A中的元素分别与集合B中的元素比较,若与其中之一相等,则存入集合A、B的交集中
if (Array1[i] == Array2[j])
{
Array3[length3] = Array2[j];
length3++;
continue;
//break;
}
}
}
//返回集合A、B的交集中元素个数,便于交集元素的输出与遍历
return length3;
}
//3.集合的并集:arrD[200] lengthD
//Array1、Array4分别代表:用户创建的集合A、B;Array2代表集合A、B的交集;Array3代表集合A、B的并集
//length1、length2、length3、length4分别为:对应集合中存储元素的个数
int Union(int Array1[], int length1, int Array2[], int length2, int Array3[], int length3, int Array4[], int length4)
{
int num = 0;
for (int i = 0; i < length1; i++)
{
for (int j = 0; j < length2; j++)
{
//将集合A中的元素分别与集合A、B交集中的元素比较,若与其中之一相等,将num赋为1,后续不再输入集合A、B的并集中
if (Array1[i] == Array2[j])
{
num = 1;
break;
}
}
//num=0时表示:当时遍历的元素在集合A中而不在集合B中,则添加入集合A、B的并集中
if (num == 0)
{
Array3[length3] = Array1[i];
length3++;
}
}
//将集合B中的元素全部添加到集合A、B的并集中,使集合A、B的并集完整
for (int k = 0; k < length4; k++)
{
Array3[length3] = Array4[k];
length3++;
}
//返回集合A、B的并集中元素个数,便于并集元素的输出与遍历
return length3;
}
//4.集合的差集:arrE[100] lengthE
//Array1、Array2、Array3分别代表:用户创建的集合A、B,集合A、B的差集
//length1、length2、length3分别为:对应集合中存储元素的个数
int Errand(int Array1[], int length1, int Array2[], int length2, int Array3[], int length3)
{
for (int i = 0; i < length1; i++)
{
int num = 0;
for (int j = 0; j < length2; j++)
{
将集合A中的元素分别与集合A、B交集中的元素比较,若与其中之一相等,将num赋为1,后续不再输入集合A、B的差集中
if (Array1[i] == Array2[j])
{
num = 1;
break;
}
}
//num=0时表示:当时遍历的元素在集合A中而不在集合B中,则添加入集合A、B的差集中
if (num == 0)
{
Array3[length3] = Array1[i];
length3++;
}
}
//返回集合A、B的差集中元素个数,便于差集元素的输出与遍历
return length3;
}
int main()
{
showMenu(); //显示操作的菜单
while (choose != 0) //循环结构,方便用户多次使用
{
cout << "请选择要进行的操作:" << endl;
cin >> choose;
switch (choose)
{
case 1: //1---输入集合A和B
{
//1.创建集合A,并将相应元素存于数组arrA中
//2.得到集合A中元素的个数
lengthA = createArray(arrA);
//判断集合A中是否有重复元素;若有,做出必要提示;若无,将集合输出便于用户操作
int numA = checkArray(arrA, lengthA);
if (numA == 0)
{
cout << "您输入的集合中有重复元素,不符合规定,请重新输入!" << endl;
cout << endl;
break;
}
else
{
cout << "你构造的集合A为:";
showArray(arrA, lengthA); //调用集合输出函数
}
cout << endl;
//1.创建集合B,并将相应元素存于数组arrA中
//2.得到集合B中元素的个数
lengthB = createArray(arrB);
//判断集合B中是否有重复元素;若有,做出必要提示;若无,将集合输出便于用户操作
int numB = checkArray(arrB, lengthB);
if (numB == 0)
{
cout << "您输入的集合中有重复元素,不符合规定,请重新输入!" << endl;
break;
}
else
{
cout << "你构造的集合B为:";
showArray(arrB, lengthB); //调用集合输出函数
}
cout << endl;
//cout << "lengthA=" << lengthA << " lengthB=" << lengthB << " lengthC=" << lengthC << endl;
break;
}
case 2: //2---求集合A交B
{
//调用Intersection()函数,求解集合A、B的交集,并返回交集中元素的个数
lengthC = Intersection(arrA, lengthA, arrB, lengthB, arrC, lengthC);
//cout << "lengthA=" << lengthA << " lengthB=" << lengthB << " lengthC=" << lengthC << endl;
cout << "集合A与B的交集为: ";
showArray(arrC, lengthC); //调用集合输出函数
cout << endl;
break;
}
case 3: //3---求集合A并B
{
//调用Union()函数,求解集合A、B的并集,并返回并集中元素的个数
lengthD = Union(arrA, lengthA, arrC, lengthC, arrD, lengthD, arrB, lengthB);
cout << "集合A与B的并集为: ";
showArray(arrD, lengthD); //调用集合输出函数
cout << endl;
break;
}
case 4: //4---求集合A-B
{
//调用Errand()函数,求解集合A、B的差集,并返回差集中元素的个数
lengthE = Errand(arrA, lengthA, arrC, lengthC, arrE, lengthE);
cout << "集合A与B的差集为: ";
showArray(arrE, lengthE); //调用集合输出函数
cout << endl;
break;
}
case 0: //退出
{
cout << "欢迎再次使用" << endl;
Sleep(3000); //延时3秒
system("cls"); //清屏操作
break;
}
default: //对不正确的输入做出提示
cout << "没有此操作,请重新输入!" << endl;
cout << endl;
break;
}
}
return 0;
}
运行结果: