C++(数据结构)集合的交并差

这篇博客介绍了如何使用C++进行数据结构中的集合操作,包括交集、并集和差集。实验要求集合元素输入时检查重复,不允许有重复元素,并将各运算实现为独立函数。通过菜单交互,用户可以反复查看结果,输入负数退出程序。文章提供了静态数组和动态数组两种实现方式,并包含测试用例。

实验1 集合的交并差


要求:
(1)实验目的
通过该实验,让学生复习巩固C语言中的循环结构、循环控制条件、分支结构和数组/链表、函数的调用等有关内容,体会到用数组存储集合时,需要记录集合元素的个数,否则输出结果会出现数据越界现象。
(2)实验内容
通过键盘,分别输入两个数据元素类型为正整数的集合A和B,以负数输入为结束条件,输出两个集合的交、并、差。
(3)实验要求
从程序完善性上考虑,集合元素输入时,要有检查元素重复的功能,每个集合中不允许有重复的元素。集合可以用数组也可以用链表存储。
实现交、并、差运算时,分别把代码写成函数的形式,即实现交运算的函数,实现并运算的函数,实现差运算的函数,在主函数中分别调用三个函数。
使用菜单形式对应各个操作,应允许用户反复查看结果,想结束程序时,输入负数结束,使其编成一个完整的小软件。菜单参考示例如下:
1—输入集合A和B
2—求集合A交B
3—求集合A并B
4—求集合A-B
退出,输入一个负数!
(4)验收/测试用例
输入: 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}


一丶使用静态数组全局声明,给定数组足够的初始长度,默认里面的元素为0.

#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
//先定义两个长度足够的默认数组. 
int a[100]={0};
int b[100]={0};

//记录集合的长度 
int a_len=0;
int b_len=0;


void input_a();//输入集合A
void input_b();//输入集合B
void inter_(); //交集
void union_(); //并集
void diff_();  //A-B


int main(){
	int flag=1;
	int infer;
	while(flag){
		cout<<"********************************"<<endl;
    	cout<<"********1:输入集合A和B**********"<<endl;
    	cout<<"********2:A与B的交集.***********"<<endl;
    	cout<<"********3:A与B的并集.***********"<<endl;
    	cout<<"********4.A与B的差集.***********"<<endl;
    	cout<<"********************************"<<endl;
	    cout<<"输入随机一个负数来结束本程序."<<endl;
	    cout<<"输入相应的数字,来执行相应的操作:"<<endl; 
	    cin>>infer;
	    switch(infer){
	    	case 1:
	    		int k;
	    		k=1;
	    		system("cls");
	    		input_a();
	    		for(int i=0;i<a_len-1;i++){    //每个元素依次和他后面的元素比较
	    			for(int j=i+1;j<a_len;j++){
	    				if(a[i]==a[j]){
	    					cout<<"请不要输入重复整数,重新输入."<<endl;
	    					k=0;
						}
					}
				}
				if(k==0) break;
	    		input_b();
	    		for(int i=0;i<b_len-1;i++){
	    			for(int j=i+1;j<b_len;j++){
	    				if(b[i]==b[j]){
	    					cout<<"请不要输入重复整数,重新输入."<<endl;
	    					k=0;
						}
					}
				}
				if(k==0) break;
	    		break;
	    	case 2:
	    		system("cls");
	    		cout<<"交集为:"; 
	    		inter_();
	    		break;
	    	case 3:
	    		system("cls");
	    		cout<<"并集为:";
	    		union_();
	    		break;
	    	case 4:
	    		system("cls");
	    		cout<<"A-B为:";
	    		diff_();
	    		break;
	    	default:
	    		system("cls");
	    		if(infer<0){
	    			flag=0;
	    			cout<<"程序退出成功!"<<endl;
	    			break;
	    		}
	    		else cout<<"您输入的指令有误,请重新输入!"<<endl;
	    }
	}
	return 0;
}


void input_a(){    //相当于对数组中的元素复写
	int i;
	cout<<"请输入数值于数组a中(以输入负数为结束的标志):";
	for(i=0;a[i]>=0;i++){
		cin>>a[i];
		/*for(int j=0;j<i;j++){
			if(a[i]==a[j]){
				cout<<"输入的数与之前相同,请重新输入."<<endl;
				return;
			}
		}*/
		if(a[i]<0) break;
	}
	cout<<"集合a输入完毕!"<<endl;
	a_len=i;   //实用元素的长度
}

void input_b(){
	cout<<"请输入数值于数组b中(以输入负数为结束的标志):";
	int i;
	for(i=0;b[i]>=0;i++){
		cin>>b[i];
		/*for(int j=0;j<i;j++){
			if(b[i]==b[j]){
				cout<<"输入的数与之前相同,请重新输入."<<endl;
				return;
	        }
	    }*/
	    if(b[i]<0) break;
	}
	cout<<"集合b输入完毕!"<<endl;
	b_len=i;
}

void inter_(){
	for(int i=0;i<a_len;i++){
		for(int j=0;j<b_len;j++){
			if(a[i]==b[j]){
				cout<<" "<<a[i];
			}
		}
	}
	cout<<endl;
}

void union_(){   //先将A中元素输出,在B中找到与之不同的再输出
	for(int i=0;i<a_len;i++){
		cout<<" "<<a[i];
	} 
	//下面的一遍历多建议多看 
	int transfer; 
	for(int i=0;i<b_len;i++){
		transfer=1;
		for(int j=0;j<a_len;j++){
			if(b[i]==a[j]){
				transfer=0;
				break;	
			}
		}
		if(transfer==1){
			cout<<" "<<b[i];
		}	
	}
	cout<<endl; 
}

void diff_(){
	int transfer;
	for(int i=0;i<a_len;i++){
		transfer=1;
		for(int j=0;j<b_len;j++){
			if(a[i]==b[j]){
				transfer=0;
				break;
			}
		}
		if(transfer==1)
		cout<<a[i]<<" ";
	}
	cout<<endl;
}

二丶利用了动态数组的方式,传参相对比较麻烦,但是节省内存有借鉴,写的不好,记录一下)
代码如下

#include <iostream>
#include<stdlib.h>
using namespace std;
int inter_(int*A,int*B,int m,int n){   //交集 
	int length=m>n?m:n;
	int*size=(int*)malloc(sizeof(int)*length);
	int c=0;
	for(int i=0;i<m;i++){
		for(int j=0;j<n;j++){
			if(A[i]==B[j]){
				size[c++]=A[i];
			}
		}
	}
	length=c;
	cout<<"输出A与B的交集:"<<endl;
	for(int i=0;i<length;i++){
		cout<<size[i]<<" ";
	}
	cout<<endl;	
}
int union_(int*A,int*B,int m,int n){   //并集 
	int len=m,judge=1;
	int*size=(int*)malloc(sizeof(int)*(m+n));
	for(int i=0;i<m;i++){
		size[i]=A[i];
	}
	for(int i=0;i<n;i++){
		judge=1;
		for(int j=0;j<m;j++){
			if(B[i]==size[j]){
				judge=0;
			}
		}
		if(judge){
			size[len]=B[i];
			len++;
		}
	}
	cout<<"输出A与B的并集:"<<endl;
	for(int i=0;i<len;i++){
		cout<<size[i]<<" ";
	}
}
int differ_(int*A,int*B,int m,int n){   //差集 
	for(int i=0;i<m;i++){
		for(int j=0;j<n;j++){
			if(A[i]==B[j]){
				break;
			}
			if(j==n-1){
				cout<<A[i]<<" ";
			}
		}
	}
	cout<<endl;	
}
	

	


int main(){
        int m,n; //集合中元素的个数
	    cout<<"输入集合A的长度:";
       	cin>>m;
		cout<<"输入集合B的长度:";
		cin>>n;
		int A[m];     //不推荐这样定义
		int B[n];
		int due;
		due=1;
	while(due>0){
    	cout<<"********************************"<<endl;
    	cout<<"********1:输入集合A和B**********"<<endl;
    	cout<<"********2:A与B的交集.***********"<<endl;
    	cout<<"********3:A与B的并集.***********"<<endl;
    	cout<<"********4.A与B的差集.***********"<<endl;
    	cout<<"********************************"<<endl;
	    cout<<"输入随机一个负数来结束本程序."<<endl;
	    cout<<"输入相应的数字,来执行相应的操作:"<<endl; 
    	cin>>due;
	    if(due==1){
			cout<<"输入集合A:"<<endl;
			int i;
			for(i=0;i<m;i++){
			cin>>A[i];
			} 
			cout<<"输入集合B:"<<endl;
			for(i=0;i<n;i++){
			cin>>B[i];
			}
			for(i=0;i<m-1;i++){            //查重 
				for(int x=i+1;x<m;x++)
					if(A[i]==A[x]){
						cout<<"请不要输入重复整数,请重新输入.";
						break;
					}
			for(i=0;i<m-1;i++){
				for(int x=i+1;x<m;x++)
					if(B[i]==B[x]){
						cout<<"请不要输入重复整数,请重新输入.";
						break;
					}
		}
			cout<<endl;
			cout<<endl;
     }
    }  
	    if(due==2){
			inter_(A,B,m,n);
			cout<<endl;
	}
	    if(due==3){
			union_(A,B,m,n);
			cout<<endl;
	}
        if(due==4){
        	cout<<endl;
        	cout<<endl;
			differ_(A,B,m,n);
			cout<<endl;
		}
		if(due>4){
			cout<<"请按操作提示输入,不要乱输."; 
			cout<<endl;
			cout<<endl;
		}
	
}
    cout<<"结束本程序";
	return 0;
}
在这里插入代码片
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值