当前位置:文档之家› 集合的并、交和差运算

集合的并、交和差运算

集合的并、交和差运算题目:编制一个演示集合的并、交和差运算的程序班级:姓名:学号:完成日期:一、需求分析1.本演示程序中,集合的元素限制在小写字母‘a’-‘z’之间。

集合的大小不限制,集合的输入形式为一个以“回车符”为结束标志的字符串,串中字符顺序不限,且允许出现重复字符或非法字符,程序运用时自动过滤去,输出的运算结果中将不含重复字符和非法字符。

2.演示程序以用户和计算机对话的形式进行,即在计算机终端中显示提示信息之后,有用户自行选择下一步命令,相应输入数据和运算结果在其后显示。

3.程序的执行命令有:1)选择操作2)任意键清屏4.数据测试(1)Set1=”magazine”, Set2=’paper”,Set1∪Set2=”aegimnprz”,Set1∩Set2=”ae”,Set1-Set2=”gimnz”;(2) Set1=”012oper4a6tion89”,Set2=”error data”,Set1∪Set2=”adeinoprt”,Set1∩Set2=”aeort”, Set1-Set2=”inp”.二、概要设计为实现上述功能,需要顺序表这个抽象数据类型。

1.顺序表抽象数据类型定义ADT sqlist{数据对象:D={ai|a i∈Elemset,i=1,2,3,…n,n>=0}数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2, … n}基本操作:InitList(&l)操作结果:构造一个空的顺序表l。

ListLength(l)初始条件:顺序表l已存在。

操作结果:返回l中的元素个数。

ListInsert_Sq(&L, i, e)初始条件:顺序表l已存在。

操作结果:在l中第i个元素前面插入元素e。

CreatSqList(&l, a[],n)初始条件:顺序表l已存在。

操作结果:将数组a[n]每个元素赋给顺序表l。

GetElem(L, i, &e)初始条件:顺序表l已存在。

操作结果:返回l中第i个元素的值LocateElem_Sq(L, e, Status (*compare)())初始条件:顺序表l已存在。

操作结果:依次遍历l中每个元素带入函数。

ListDelete(&L,i, &e)初始条件:顺序表l已存在。

操作结果:删除顺序表中第i个元素。

Outputlist(&L)初始条件:顺序表l已存在。

操作结果:输出顺序表的每个元素值。

}ADT sqlist三、详细设计// 程序的头文件#include<stdio.h>#include<malloc.h>#include<stdlib.h>#include<string.h>// 函数返回值#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define INFEASIBLE -1#define OVERFLOW -2#define NULL 0#define LIST_INIT_SIZE 100 //顺序表的初始大小#define LISTINCREMENT 10 //顺序表的递增大小typedef int Status; //返回状态类型typedef char ElemType; //元素类型typedef struct{ElemType *elem;int length;int listsize;}SqList; //结点类型指针类型Status InitList(SqList &l){//初始化顺序表l.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!l.elem) exit(OVERFLOW);l.length=0;l.listsize=LIST_INIT_SIZE;return OK;int ListLength(SqList l){//求顺序表的长度return(l.length);}Status ListInsert_Sq(SqList &L,int i, ElemType e){//在顺序表L的第i个位置前插入元素e,i的合法值为1..L.length+1 if(i<1||i>L.length+1)return ERROR;if(L.length>=L.listsize){ElemType*newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase) exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}ElemType *q=&L.elem[i-1], *p=&L.elem[L.length-1];while(p>=q){*(p+1)=*p; --p;} //插入位置后的元素右移*q=e;++L.length;return OK;}Status CreatSqList(SqList &l,ElemType a[],int n){//创建顺序表int len=ListLength(l);for(int i=0;i<n;i++){if(a[i]>='a'&&a[i]<='z')ListInsert_Sq(l,++len,a[i]);}return OK;}Status GetElem(SqList L,int i,ElemType &e)// 返回顺序表中元素if(i<=0||i>L.length)return ERROR;elsee=*(L.elem+i-1);return OK;}Status equal(ElemType e1,ElemType e2){if(e1==e2)return TRUE;elsereturn FALSE;}int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType,ElemType)) {ElemType *p=L.elem; //p指向第一个元素int i=1; //i始终为p所指向元素的位序while(i<=L.length&&!(*compare)(*p++,e))++i;if(i<=L.length)return(i);elsereturn 0;}Status ListDelete(SqList &L,int i,ElemType &e){//在顺序表L中删除第i个元素,用e返回其值.if(i<1||i>L.length)return ERROR;//删除位置不合理ElemType *p=&L.elem[i-1],*q=L.elem+L.length-1;e=*p;while(p<q){*p=*(p+1); ++p;} //删除位置后的元素左移--L.length;return OK;}void Union(SqList &La,SqList Lb){//将所有在线性表Lb中而不在La中的元素插入Laint la_len , lb_len;ElemType e;la_len=ListLength(La);lb_len=ListLength(Lb);for(int i=1;i<=lb_len;++i){GetElem(Lb,i,e);if(LocateElem_Sq(La,e,equal)==0)ListInsert_Sq(La,++la_len,e);}}Status JiaoJi(SqList l1,SqList l2, SqList &l3) {//求集合的交集int l1_len, l2_len,l3_len,i=1,j=1;ElemType e,u;l1_len=ListLength(l1);l2_len=ListLength(l2);l3_len=ListLength(l3);for(i=1;i<=l1_len;i++){GetElem(l1,i,e);for(j=l2_len;j>=1;j--){GetElem(l2,j,u);if(e==u){ListInsert_Sq(l3,++l3_len,u);break;}elsecontinue;}}return OK;}Status ChaJi(SqList &l1,SqList l2){//求顺序表的差集SqList lc;int count=0,lc_len,l1_len,l2_len;ElemType e,u,f;InitList(lc);JiaoJi(l1,l2,lc);lc_len=ListLength(lc);l1_len=ListLength(l1);l2_len=ListLength(l2);for(int i=1;i<=lc_len;i++){GetElem(lc,i,e);for(int j=1;j<=l1_len;j++){GetElem(l1,j,u);if(u==e){ListDelete(l1,j,f);}}}return OK;}void Outputlist(SqList &L){if(0==L.length)printf("空集!");elsefor(int i=0;i<L.length;++i){printf("%c",*(L.elem+i));}}//程序的主函数void main(){system("@title 集合的并交叉运算");for(1;;){system("color a1");int c;printf("****************************************************************\n");printf(" ######## 执行程序: 1 ######## 退出程序: 2\n");printf("****************************************************************\n");printf("请按键选择: ");scanf("%d",&c);getchar();printf("\n");if(c==1){SqList l1,l2,l3,la;int n1,n2,i,j;char a1[30], a2[30];InitList(l1);InitList(l2);InitList(l3);InitList(la);printf("请输入第一个集合: ");gets(a1);n1=strlen(a1);for(i=n1-1;i>=0;i--) //从最后一个开始依次与前面的比较重复赋值为0{for(j=0;j<i;j++){if(a1[j]==a1[i])a1[i]=0;}}CreatSqList(l1,a1,n1);la=l1;printf("请输入第二个集合: ");gets(a2);n2=strlen(a2);for(i=n2-1;i>=0;i--) //同上{for(j=0;j<i;j++){if(a1[j]==a1[i])a1[i]=0;}}CreatSqList(l2,a2,n2);printf("集合的交集是: ");JiaoJi(l1,l2,l3);Outputlist(l3);printf("\n");printf("集合的并集是: ");Union(l1,l2);Outputlist(l1);printf("\n");printf("集合的差集是: ");ChaJi(la,l2);Outputlist(la);printf("\n\n*****************按*任*意*键*清*屏!********************");system("pause>null");system("cls");}elseexit(0);}}四、调试分析1.本程序的模块划分比较合理,且尽可能的将指针的操作封装在结点和链表的两个模块中,致使集合模块的调试比较成功。

相关主题