實驗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 }
剛才經過老師的講解,我發現了我的并集是追求表現形式,先把兩個數組的相同項标記出來,然後分别對兩個數組各自查重,有重的都标記出來,最後分别輸出沒有标記的兩個數組中的元素,但這實際上是還是兩個集合,雖然輸出的也是并集,但是思路邏輯上,我還是把它們當成兩個數組來輸出,而不符合題目的要求并集,這代表了一個集合,是以我第一種方法隻是追求了形式的正确,而沒有真正用并集的思想,一個集合,第二種方法是讓他們合成一個集合是正确的