实验2、集合的交、并、差 (1学时)
(1)实验目的
通过该实验,进一步让学生熟练掌握循环结构、循环控制条件、分支结构和数组/链表基本操作的实现,掌握函数参数设定的有关内容,体会到用数组存储集合时,需要记录集合元素的个数,否则输出结果会出现数据越界现象。
(2)实验内容
通过键盘,分别输入两个数据元素类型为正整数的集合A和B,以负数输入为结束条件,输出两个集合的交、并、差。从程序完善性上考虑,集合元素输入时,要有检查元素重复的功能。集合可以用数组也可以用链表存储。
(3)验收/测试用例
输入: A={1,2,3,4,5} B={3,4,5,6,7}
输出 A交B={3, 4, 5} A并B={1,2,3,4,5,6,7} A-B={1, 2},B-A={6,7}
1 #include<iostream>
2 using namespace std;
3 #define N 1000
4 void jiaoji(int a[N],int b[N],int num1,int num2)
5 {
6 int c[N],num=0;
7 for(int i=0;i<num1;i++)
8 for(int j=0;j<num2;j++)
9 {
10 if(a[i]==b[j])
11 {
12 c[num]=a[i];
13 num++;
14 }
15 }
16 for(int i=0;i<num;i++)
17 printf("%d ",c[i]);
18 printf("\n");
19 }
20 void acha(int a[N],int b[N],int num1,int num2)
21 {
22 int c[N],num=0,m;
23 for(int i=0;i<num1;i++)
24 {
25 m=0;
26 for(int j=0;j<num2;j++)
27 {
28 if(a[i]==b[j])
29 {
30 m=1;
31 break;
32 }
33 }
34 if(m==0)
35 {
36 c[num]=a[i];
37 num++;
38 }
39 }
40 for(int i=0;i<num;i++)
41 printf("%d ",c[i]);
42 printf("\n");
43 }
44 void bcha(int a[N],int b[N],int num1,int num2)
45 {
46 int c[N],num=0,m;
47 for(int j=0;j<num2;j++)
48 {
49 m=0;
50 for(int i=0;i<num1;i++)
51 {
52 if(a[i]==b[j])
53 {
54 m=1;
55 break;
56 }
57 }
58 if(m==0)
59 {
60 c[num]=b[j];
61 num++;
62 }
63 }
64 for(int j=0;j<num;j++)
65 printf("%d ",c[j]);
66 printf("\n");
67 }
68 void bingji(int a[N],int b[N],int num1,int num2)
69 {
70 for(int i=0;i<num1;i++)
71 for(int j=0;j<num2;j++)
72 {
73 if(a[i]==b[j])
74 {
75 a[i]=-1;
76 continue;
77 }
78
79 }
80 for(int i=0;i<num1;i++)
81 for(int j=0;j<i;j++)
82 if(a[j]==a[i])
83 a[i]=-1;
84 for(int i=0;i<num1;i++)
85 if(a[i]!=-1)
86 printf("%d ", a[i]);
87
88 for(int i=0;i<num2;i++)
89 for(int j=0;j<i;j++)
90 if(b[j]==b[i])
91 b[i]=-1;
92 for(int i=0;i<num2;i++)
93 if(b[i]!=-1)
94 printf("%d ", b[i]);
95
96 }
97 int main()
98 {
99 int a[N],b[N],num1,num2;
100 for(int i=0;i<N;i++)
101 {
102 scanf("%d", &a[i]);
103 num1=i;
104 if(a[i]<0)
105 break;
106 }
107 for(int i=0;i<N;i++)
108 {
109 scanf("%d", &b[i]);
110 num2=i;
111 if(b[i]<0)
112 break;
113 }
114 jiaoji(a,b,num1,num2);
115 acha(a,b,num1,num2);//a-b的差
116 bcha(a,b,num1,num2);//b-a的差
117 bingji(a,b,num1,num2);//为什么不能放到115行 ???
118
119
120 }
求并集在我的CSDN博客上也有https://blog.csdn.net/acmer6s/article/details/80435334
CSDN上的并集是我上学期在学习C++时而用到的两种方法,但第二种方法中的并集查重是一个重点!
缺陷1:目前疑问就是bingji(a,b,num1,num2)为什么放到115行就发生bug,bug出现是如果移动到115行的话,那么a-b便会输出1,2,-1,-1,-1类似这个,可能是数组越界但是也不应该啊,下午上课问问老师吧
缺陷2:在集合输入中自己并没有用查重的功能,所以会出现集合中有相同的元素
----------------------------------------------------------
16:30:05刚才老师讲了一个求并集的方法解决了我的缺陷1
并集核心代码如下
1 void bingji(int a[N],int b[N],int num1,int num2) 2 { 3 int c[N]; 4 for(int i=0;i<num1;i++) 5 c[i]=a[i]; 6 for(int j=0;j<num2;j++) 7 c[j+num1]=b[j];--
/*上面是为了让a,b两个数组都弄到c数组中*/
/*下面的代码是用来查重*/ 8 for (int i=0;i<num1+num2-1;i++) 9 for(int j=i+1;j<num1+num2;j++)// 10 { 11 if(c[i]==c[j]) 12 c[i]=-1; 13 } 14 for(int i=0;i<num1+num2;i++) 15 if(c[i]>=0) 16 { 17 printf("%d ",c[i]); 18 } 19 printf("\n"); 20 21 }
刚才经过老师的讲解,我发现了我的并集是追求表现形式,先把两个数组的相同项标记出来,然后分别对两个数组各自查重,有重的都标记出来,最后分别输出没有标记的两个数组中的元素,但这实际上是还是两个集合,虽然输出的也是并集,但是思路逻辑上,我还是把它们当成两个数组来输出,而不符合题目的要求并集,这代表了一个集合,所以我第一种方法只是追求了形式的正确,而没有真正用并集的思想,一个集合,第二种方法是让他们合成一个集合是正确的