zoukankan      html  css  js  c++  java
  • 离散数学实验——集合的运算

    实验一 集合的运算

    1.1实验目的

    集合论是一切数学的基础,也是计算机科学不可或缺的,在数据结构、数据库理论、开关理论、自动机理论和可计算理论等领域都有广泛的应用。集合的运算规则是集合论中的重要内容。通过该组实验,目的是让学生更加深刻地理解集合的概念和性质,并掌握集合的运算规则等。

    1.2实验内容

    1、选用恰当的数据结构实现集合的存储;(数组、向量)

    2、实现集合的基本操作:查找、插入、删除、输出;

    3、判断某个元素是否属于集合;

    4、实现集合的基本运算:并、交、差、对称差运算;

    5、判断两集合之间的关系:包含、相等;

    6、求集合的幂集并输出。

    1.3主要算法思想

      集合的交:

            把需要求交集的集合中的元素全部放在一个新的字符串allElem中,比如A{a,b,c,d}B{a,d,e,f,g},allElem=abcdadefg”。

         然后利用两次循环计算allElem中的每个字符出现的个数,用InNum记录。计算完一个字符后,InNum归零。

         如果InNum=集合的个数,则说明当前元素在所有的集合里,所以输出当前元素。

    //计算交集(多个集合进行计算)
    string ListIntersect(string &SelectedList) {
    	string NewList="";
    	ListAllOutput();
    	cout << endl << "请选择需要求交集的集合:";
    	cin >> SelectedList;
    	//把所有集合放在一个字符穿里  
    	string allElem="";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    
    	//判断allElem出现了选中集合数量的次数
    	for (int i = 0; i < allElem.length(); i++) {
    		int InNum = 0;
    		for (int j =i; j < allElem.length(); j++) {
    			if (allElem[i] == allElem[j])
    				InNum++;
    		}
    		if (InNum == SelectedList.length())
    		{
    			NewList += allElem[i];
    		}
    	}
    	cout << "交集为";
    	return NewList;
    }
    

     

    集合的并:

         把需要求并集的集合中的元素全部放在一个新的字符串allElem中,比如A{a,b,c,d}B{a,d,e,f,g},allElem=abcdadefg”。

         然后先利用InNum求出元素在allElem出现的次数,然后依次输出allElem的元素,如果出现两次,则只输出一次。

    //计算并集(多个集合进行计算)
    string ListUnion(string &SelectedList) {
    	string NewList="";
    	ListAllOutput();
    	cout << endl << "请选择需要求并集的集合:";
    	cin >> SelectedList;
    	bool flag;
    	//把所有集合放在一个字符穿里  
    	string allElem = "";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    	//cout << "集合" << SelectedList << "的并集为:{";
    	//排除allElem的重复元素就是并集
    	for (int i = 0; i < allElem.length(); i++) {
    		int InNum = 0;
    		flag = true;
    		for (int j = i; j < allElem.length(); j++) {
    			if (allElem[i] == allElem[j])
    				InNum++;
    		}
    		if (InNum <= 1)
    		{
    			NewList += allElem[i];
    		}
    			
    	}
    	cout << "并集为";
    	return NewList;
    }
    

      集合的差:

           输入:集合名1-集合名2

         利用两层循环,第一层遍历集合名1的元素,第二层遍历集合名2的元素,并判断集合名1中的元素是否在集合名2中,如果在则不输出。

    //计算差集(也就是相对补集,,两个集合进行计算)
    string ListSubtract(string &SelectedList) {
    	while (true) {
    		ListAllOutput();
    		cout << endl << "注意:求差集集合名顺序不能改变"<<endl<<"例如:集合A:{a,b,c,d} B:{c,d,e,f}"<<endl<<"	则A-B={a,b}    B-A={e,f}";
    		cout << endl << "请按照 ‘集合名1-集合名2’输入:";
    		cin >> SelectedList;
    		if (SelectedList.length() > 3)
    			cout << "输入有误!请重新输入!" << endl;
    		else
    			break;
    	}
    	int List1Length = List[int(SelectedList[0]) - 65].length();
    	int List2Length = List[int(SelectedList[2]) - 65].length();
    	string NewList="";//保存
    	bool flag;
    	//cout << "" << SelectedList << "的集合为:{";
    	for (int i = 0; i < List1Length; i++)//循环集合名1的长度
    	{
    		flag = true;
    		for (int j = 0; j < List2Length; j++)//循环集合名2的长度   冒泡遍历  依次用集合名1的元素跟所有集合名2中的元素比较  有相同则除去
    		{
    			if (List[int(SelectedList[0]) - 65][i] == List[int(SelectedList[2]) - 65][j])//集合名1中的第i个元素等于集合名2中的第j个元素
    			{
    				flag = false;
    				break;
    			}
    		}
    		if(flag)
    			NewList += List[int(SelectedList[0]) - 65][i];
    
    	}
    	cout << "差集为";
    	return NewList;
    
    }
    

      

    集合的对称差:

         将求对称差的集合中的元素全部放在一个新的字符串allElem中。

       定义一个flag,利用两层循环将allElem中的每个元素于其他元素比较,若相等则是交集就不输出,若没有相等的则说明不是交集就输出。

    //计算对称差(可以多个集合计算)
    string ListSymDifference(string& SelectedList) {
    	string NewList = "";
    	ListAllOutput();
    	cout << endl << "请选择需要求对称差的集合:";
    	cin >> SelectedList;
    	bool flag;
    	//把所有集合放在一个字符穿里  
    	string allElem = "";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    	for (int i = 0; i < allElem.length(); i++) {
    		flag = true;
    		for (int j = 0; j < allElem.length(); j++) {
    			if (i == j)
    				continue;
    			if (allElem[i] == allElem[j])
    			{
    				flag = false;
    				break;
    			}
    		}
    		if (flag) {
    			NewList += allElem[i];
    		}
    	}
    	cout << "对称差为";
    	return NewList;
    }
    

      

    集合求幂集:

         利用三层循环,第一层循环是计算i元子集。

         第二层循环是计算包含第j个元素的所有i元子集

         第三层循环则是第j个元素的i元子集的所有组合。

    //求幂集
    void PowerSet() {
    	char ListName;//需要求幂集的集合名
    	ListAllOutput();
    	cout << endl << "请选择要求幂集的集合:";
    	cin >> ListName;
    	string PowerSet;//幂集字符串
    	int ListLength = List[int(ListName) - 65].length();
    	cout << "{{},";//首先输出空集
    	for (int i = 1; i <= ListLength; i++) {//第一层循环是计算几元子集
    		/// <summary>
    		/// 第二层循环是计算包含第j+1个元素的所有i元子集
    		/// 例如:A{a,b,c,d}  
    		/// 当j=0 i=1,则有{a}
    		/// 当j=0 i=2,则有{a,b} {a,c} {a,d}
    		/// </summary>
    		for (int j = 0; j < ListLength; j++) {
    			if (j + i > ListLength)
    				break;
    			//求一元子集直接求
    			if (i == 1) {
    				cout << "{" << List[int(ListName) - 65][j] << "},";
    			}
    			else
    			{
    				//其他元子集利用循环求
    				int n = 0;
    				for (int k = j + 1; k < ListLength; k++) {
    					if (n == 0)
    					{
    						cout << "{";
    						cout << List[int(ListName) - 65][j];
    					}
    					n++;
    					if (n == i)
    					{
    						k=k-i+1;
    						n = 0;
    						cout << "},";
    						continue;
    					}
    					else
    					{
    						cout << "," << List[int(ListName) - 65][k];
    					}
    				}
    				if (i == ListLength)
    					cout << "}";
    				else
    					cout << "},";
    			}
    		}
    	}
    	cout << "}";
    }
    

      

    完整代码:

    #include<iostream>
    #include<string>
    using namespace std;
    #define MAXSIZE 26
    
    string* List=new string[MAXSIZE];//定义全局集合数组
    int ListNum=0;//定义全局变量集合的数量
    //创建集合
    void ListCreat() {
    	if (ListNum >= MAXSIZE) {
    		cout << "只能创建26个集合!" << endl;
    		return;
    	}
    	while (true)
    	{
    		cout << "请输入" << (char)(ListNum + 65) << "集合的的元素:";//加65是因为A的ASCII值为65让集合名称变成字母
    		cin >> List[ListNum];
    		bool flag;
    		for (int j = 0; j < List[ListNum].length(); j++) {
    			flag = true;
    			for (int k = j + 1; k < List[ListNum].length(); k++) {
    				if (List[ListNum][j] == List[ListNum][k])
    				{
    					flag = false;
    					break;
    				}
    			}
    			if (!flag)
    				break;
    		}
    		if (!flag) {
    			cout << "集合中不允许存在相同元素!,请重新输入!" << endl;;
    		}
    		else
    		{
    			break;
    		}
    	}
    	++ListNum;
    }
    /// <summary>
    /// 删除集合  当删除一个集合时它后面的的集合依次往前
    /// 比如 当前有集合 A  B  C  D时,删除B则C集合变成B集合,D集合变成C集合;
    /// 类似于顺序表
    /// </summary>
    void ListDelete() {
    	char ListName;
    	cout << "请输入集合的名称:";
    	cin >> ListName;
    	if ((int(ListName) - 65) > ListNum)//没有创建那么多集合
    	{
    		cout << "没有该集合!";
    	}
    	else {
    		for (int i = (int(ListName) - 65); i < ListNum; i++) {
    			List[i] = List[i + 1];
    		}
    		--ListNum;
    	}
    }
    
    
    
    
    //规范化输出集合,用于集合的基本运算
    void StandardOutput(string elems) {
    	cout << ":{";
    	for (int i = 0; i < elems.length(); i++)
    	{
    		if (i != elems.length() - 1)
    			cout << elems[i] << ",";
    		else
    			cout << elems[i];
    	}
    	cout << "}" << endl;
    }
    //查找
    void ElemLocate(char ListName) {
    	int ListLength = List[int(ListName) - 65].length();
    	char elem;//要查找的元素
    	cout << "请输入要查找的元素:";
    	cin >> elem;
    	for (int i = 0; i < ListLength; i++) {
    		if (List[int(ListName) - 65][i] == elem)
    		{
    			cout << elem << "是第" << i + 1 << "个元素";
    			return;
    		}
    	}
    	cout << "该集合没有该元素!";
    }
    //插入,直接在字符串最后面插入
    void ElemInsert(char ListName) {
    	char elem;//要查找的元素
    	cout << "请输入要插入的元素:";
    	cin >> elem;
    	List[int(ListName) - 65] += elem;
    }
    //删除
    void ElemDelete(char ListName) {
    	int ListLength = List[int(ListName) - 65].length();
    	char elem;//要删除的元素
    	cout << "请输入要删除的元素:";
    	cin >> elem;
    
    	for (int i = 0; i < ListLength; i++)
    	{
    		if (List[int(ListName) - 65][i] == elem) {
    			List[int(ListName) - 65].erase(i,1);
    			return;
    		}
    	}
    	cout << "该集合没有该元素!";
    }
    //输出集合元素
    void ListOutput(char ListName) {
    
    		cout << "集合" << ListName<<":{";
    	for (int i = 0; i < List[int(ListName) - 65].length(); i++)
    	{
    		if(i != List[int(ListName)-65].length() - 1)
    			cout << List[int(ListName) - 65][i] << ",";
    		else
    			cout << List[int(ListName) - 65][i];
    	}
    	cout << "}" << endl;
    }
    //判断某个元素是否属于集合
    bool IsBelong(char elem,char ListName) {
    	int ListLength = List[int(ListName) - 65].length();
    	for (int i = 0; i < ListLength; i++) {
    		if (elem == List[int(ListName) - 65][i])
    			return true;
    	}
    	return false;
    }
    //输出所有集合
    void ListAllOutput() {
    	cout << "当前集合有:" << endl;
    	for (int i = 0; i < ListNum; i++) {
    		cout << "集合" << (char)(i + 65) << ":{";
    		for (int j = 0; j < List[i].length(); j++) {
    			if (j != List[i].length() - 1)
    				cout << List[i][j] << ",";
    			else
    				cout << List[i][j];
    		}
    		cout << "}" << endl;
    	}
    }
    #pragma region 集合的基本运算
    //计算交集(多个集合进行计算)
    string ListIntersect(string &SelectedList) {
    	string NewList="";
    	ListAllOutput();
    	cout << endl << "请选择需要求交集的集合:";
    	cin >> SelectedList;
    	//把所有集合放在一个字符穿里  
    	string allElem="";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    
    	//判断allElem出现了选中集合数量的次数
    	for (int i = 0; i < allElem.length(); i++) {
    		int InNum = 0;
    		for (int j =i; j < allElem.length(); j++) {
    			if (allElem[i] == allElem[j])
    				InNum++;
    		}
    		if (InNum == SelectedList.length())
    		{
    			NewList += allElem[i];
    		}
    	}
    	cout << "交集为";
    	return NewList;
    }
    //计算并集(多个集合进行计算)
    string ListUnion(string &SelectedList) {
    	string NewList="";
    	ListAllOutput();
    	cout << endl << "请选择需要求并集的集合:";
    	cin >> SelectedList;
    	bool flag;
    	//把所有集合放在一个字符穿里  
    	string allElem = "";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    	//cout << "集合" << SelectedList << "的并集为:{";
    	//排除allElem的重复元素就是并集
    	for (int i = 0; i < allElem.length(); i++) {
    		int InNum = 0;
    		flag = true;
    		for (int j = i; j < allElem.length(); j++) {
    			if (allElem[i] == allElem[j])
    				InNum++;
    		}
    		if (InNum <= 1)
    		{
    			NewList += allElem[i];
    		}
    			
    	}
    	cout << "并集为";
    	return NewList;
    }
    //计算差集(也就是相对补集,,两个集合进行计算)
    string ListSubtract(string &SelectedList) {
    	while (true) {
    		ListAllOutput();
    		cout << endl << "注意:求差集集合名顺序不能改变"<<endl<<"例如:集合A:{a,b,c,d} B:{c,d,e,f}"<<endl<<"	则A-B={a,b}    B-A={e,f}";
    		cout << endl << "请按照 ‘集合名1-集合名2’输入:";
    		cin >> SelectedList;
    		if (SelectedList.length() > 3)
    			cout << "输入有误!请重新输入!" << endl;
    		else
    			break;
    	}
    	int List1Length = List[int(SelectedList[0]) - 65].length();
    	int List2Length = List[int(SelectedList[2]) - 65].length();
    	string NewList="";//保存
    	bool flag;
    	//cout << "" << SelectedList << "的集合为:{";
    	for (int i = 0; i < List1Length; i++)//循环集合名1的长度
    	{
    		flag = true;
    		for (int j = 0; j < List2Length; j++)//循环集合名2的长度   冒泡遍历  依次用集合名1的元素跟所有集合名2中的元素比较  有相同则除去
    		{
    			if (List[int(SelectedList[0]) - 65][i] == List[int(SelectedList[2]) - 65][j])//集合名1中的第i个元素等于集合名2中的第j个元素
    			{
    				flag = false;
    				break;
    			}
    		}
    		if(flag)
    			NewList += List[int(SelectedList[0]) - 65][i];
    
    	}
    	cout << "差集为";
    	return NewList;
    
    }
    //计算对称差(可以多个集合计算)
    string ListSymDifference(string& SelectedList) {
    	string NewList = "";
    	ListAllOutput();
    	cout << endl << "请选择需要求对称差的集合:";
    	cin >> SelectedList;
    	bool flag;
    	//把所有集合放在一个字符穿里  
    	string allElem = "";
    	for (int i = 0; i < SelectedList.length(); i++) {
    		allElem += List[int(SelectedList[i]) - 65];
    	}
    	for (int i = 0; i < allElem.length(); i++) {
    		flag = true;
    		for (int j = 0; j < allElem.length(); j++) {
    			if (i == j)
    				continue;
    			if (allElem[i] == allElem[j])
    			{
    				flag = false;
    				break;
    			}
    		}
    		if (flag) {
    			NewList += allElem[i];
    		}
    	}
    	cout << "对称差为";
    	return NewList;
    }
    //判断相等(两个集合进行计算)
    bool IsEqual(char& List1, char& List2) {
    	ListAllOutput();
    	int InNum = 0;
    	bool flag=true;
    	cout << endl << "请选择需要判断的集合(用空号隔开):";
    	cin >> List1 >> List2;
    	//如果两个集合的长度不一样 不可能相同
    	if (List[int(List1) - 65].length() != List[int(List2) - 65].length())
    		return false;
    	for (int i = 0; i < List[int(List1) - 65].length(); i++) {
    		for (int j = 0; j < List[int(List2) - 65].length(); j++) {
    			if (List[int(List1) - 65][i] == List[int(List2) - 65][j])
    			{
    				InNum++;
    				break;
    			}
    		}
    
    	}
    	if (InNum == List[int(List1) - 65].length())
    		return true;
    	else
    		return false;
    }
    //判断是否包含
    bool IsContain(char &List1,char &List2) {
    	int InNum = 0;//用来判断集合名1中的元素有几个在集合名2中 如果InNum=集合名1的长度说明  集合名2中有所有的集合名1的元素  则是包含
    	bool flag;
    	ListAllOutput();
    	cout << endl << "集合名1包含于集合名2";
    	cout << endl << "请先输入集合名1:";
    	cin >> List1;
    	cout << "请输入集合名2:";
    	cin >> List2;
    	//如果集合名1的元素比集合名2中的元素多,则不可能是包含
    	if (List[int(List1) - 65].length() > List[int(List2) - 65].length())
    		return false;
    	for (int i = 0; i < List[int(List1) - 65].length(); i++) {
    		flag = false;
    		for (int j = 0; j < List[int(List2) - 65].length(); j++) {
    			if (List[int(List1) - 65][i] == List[int(List2) - 65][j])
    			{
    				InNum++;
    				break;
    			}
    		}
    	}
    	if (InNum == List[int(List1) - 65].length())
    		return true;
    	else
    		return false;
    }
    #pragma endregion
    
    //求幂集
    void PowerSet() {
    	char ListName;//需要求幂集的集合名
    	ListAllOutput();
    	cout << endl << "请选择要求幂集的集合:";
    	cin >> ListName;
    	string PowerSet;//幂集字符串
    	int ListLength = List[int(ListName) - 65].length();
    	cout << "{{},";//首先输出空集
    	for (int i = 1; i <= ListLength; i++) {//第一层循环是计算几元子集
    		/// <summary>
    		/// 第二层循环是计算包含第j+1个元素的所有i元子集
    		/// 例如:A{a,b,c,d}  
    		/// 当j=0 i=1,则有{a}
    		/// 当j=0 i=2,则有{a,b} {a,c} {a,d}
    		/// </summary>
    		for (int j = 0; j < ListLength; j++) {
    			if (j + i > ListLength)
    				break;
    			//求一元子集直接求
    			if (i == 1) {
    				cout << "{" << List[int(ListName) - 65][j] << "},";
    			}
    			else
    			{
    				//其他元子集利用循环求
    				int n = 0;
    				for (int k = j + 1; k < ListLength; k++) {
    					if (n == 0)
    					{
    						cout << "{";
    						cout << List[int(ListName) - 65][j];
    					}
    					n++;
    					if (n == i)
    					{
    						k=k-i+1;
    						n = 0;
    						cout << "},";
    						continue;
    					}
    					else
    					{
    						cout << "," << List[int(ListName) - 65][k];
    					}
    				}
    				if (i == ListLength)
    					cout << "}";
    				else
    					cout << "},";
    			}
    		}
    	}
    	cout << "}";
    }
    
    void main() {
    	int opearateNum = 0;//操作值
    	while (true)
    	{
    		char List1, List2;//用于  判断包含和相等关系
    		cout << "0、创建集合
    1、集合的基本操作
    2、判断元素是否属于集合
    3、集合的基本运算
    4、判断是否包含
    5、判断是否相等
    6、求幂集
    输入负数退出
    请输入:";
    		cin >> opearateNum;
    		if (opearateNum < 0)
    			break;
    		switch (opearateNum) {
    		case 0:
    			ListCreat();
    			system("pause");
    			system("cls");
    			break;
    		case 1:
    			int opearateNum_2;
    			ListAllOutput();
    			char ListName;
    			cout << "请输入需要操作的集合的名称:";
    			cin >> ListName;
    			while (true) {
    				system("cls");
    				ListOutput(ListName);
    				cout << "1、查找	2、插入	3、删除	4、输出	输入负数返回
    请输入:";
    				cin >> opearateNum_2;
    				if (opearateNum_2 < 0)
    					break;
    				switch (opearateNum_2)
    				{
    				case 1:
    					ElemLocate(ListName);
    					cout << endl;
    					system("pause");
    					system("cls");
    					break;
    				case 2:
    					ElemInsert(ListName);
    					ListOutput(ListName);
    					system("pause");
    					system("cls");
    					break;
    				case 3:
    					ElemDelete(ListName);
    					ListOutput(ListName);
    					system("pause");
    					system("cls");
    					break;
    				case 4:
    					ListOutput(ListName);
    					system("pause");
    					system("cls");
    					break;
    				default:
    					cout << "无效操作!";
    					break;
    				}
    			}
    			system("pause");
    			system("cls");
    			break;
    		case 2:
    			char elem, ListName_2;
    			cout << "请输入元素值和集合名(用空号隔开):";
    			cin >> elem >> ListName_2;
    			if (IsBelong(elem, ListName_2))
    				cout << elem << "属于集合" << ListName_2 << endl;
    			else
    				cout << elem << "不属于集合" << ListName_2 << endl;
    			system("pause");
    			system("cls");
    			break;
    		case 3:
    			while (true) {
    				string SelectedList;
    				int opearateNum_3;
    				system("cls");
    				cout << "1、交	2、并	3、差	4、对称差	输入负数返回
    请输入:";
    				cin >> opearateNum_3;
    				if (opearateNum_3 < 0)
    					break;
    				switch (opearateNum_3)
    				{
    				case 1:
    					StandardOutput(ListIntersect(SelectedList));
    					system("pause");
    					system("cls");
    					break;
    				case 2:
    					StandardOutput(ListUnion(SelectedList));
    					system("pause");
    					system("cls");
    					break;
    				case 3:
    					StandardOutput(ListSubtract(SelectedList));
    					system("pause");
    					system("cls");
    					break;
    				case 4:
    					StandardOutput(ListSymDifference(SelectedList));
    					system("pause");
    					system("cls");
    					break;
    				default:
    					cout << "无效操作!";
    					break;
    				}
    			}
    			system("pause");
    			system("cls");
    			break;
    		case 4:
    			if (IsContain(List1, List2))
    				cout << List1 << "包含于" << List2; 
    			else
    				cout << List1 << "不包含于" << List2;
    			cout << endl;
    			system("pause");
    			system("cls");
    			break;
    		case 5:
    			if(IsEqual(List1, List2))
    				cout <<"集合"<< List1 << "与" << "集合"<<List2<<"相等";
    			else
    				cout << "集合" << List1 << "与" << "集合" << List2 << "不相等";
    			cout << endl;
    			system("pause");
    			system("cls");
    			break;
    		case 6:
    			PowerSet();
    			system("pause");
    			system("cls");
    			break;
    		default:
    			cout << "无效操作!";
    			break;
    		}
    
    	}
    }
    

     

  • 相关阅读:
    Django ORM操作
    django路由系统
    django(模版)
    mysql(函数,存储过程,事务,索引)
    mysql(单表查询,多表查询,MySQl创建用户和授权,可视化工具Navicat的使用)
    pycharm基本用法
    JS在浏览器中输出各种三角形
    异常处理,内置方法(__new__,__init__,__del__析构方法,单例模式,item系列)
    反射,内置方法,__str__ __repr__
    C. Swap Letters 01字符串最少交换几次相等
  • 原文地址:https://www.cnblogs.com/edllixiaoyu/p/13942776.html
Copyright © 2011-2022 走看看