数据结构课程设计——集合的交、并和差运算

news2024/12/17 12:21:24

集合的交、并和差运算

数据结构课程设计任务书

学生姓名:        专业班级: 软件工程

指导教师:        工作单位: 

题  目:  集合的并、交和差运算                                    

基础要求:

  1. 掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力。
  2. 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能。

3、提高综合运用所学的理论知识和方法独立分析和解决问题的能力。

主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

(1)任务内容

编制一个能演示执行集合的并、交和差运算的程序。

(2)完成要求

对系统进行功能模块分析、控制模块分析;系统设计要能完成题目所要求的功能;编程简练,可用,尽可能的使系统的功能更加完善和全面;说明书、流程图要清楚;提高学生的论文写作能力;特别要求自己独立完成;在基本要求达到后,可进行创新设计,如改善算法性能、友好的人机界面。

(3)撰写课程设计报告

报告格式按附件要求打印与写课程设计报告;论文包括目录、正文、小结、参考文献、附录等;课程设计论文装订按学校的统一要求完成。

时间安排:

内容                  天数             地点

构思及收集资料          1              图书馆

编码与调试              3              图书馆

撰写论文                1              图书馆

指导教师签名:                             

完整资料一键获取私信我:

 

  • 问题分析和任务定义

1.1 问题的描述

编制一个能演示执行集合的并、交和差运算的程序。

1.2 基本要求

(1) 集合的元素限定为小写字母字符 [‘a’..’z’] ,集合输入的形式为

一个以“回车符“为结束标志的字符串,串中字符顺序不限。

(2) 演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提

示信息“之后,由用户在键盘上输入演示程序中规定的运算命令﹔相应的输入数

据和运算结果显示在其后。 

1.3 程序执行的命令包括:

(1)构造集合1;

(2)构造集合2;

(3)求并集;

(4)求交集;

(5)求差集;

1.4 测试数据

(1)Set1="magazine",Set2="paper",

Set1∪Set2="aegimnprz",Setl ∩Set2="ae",Set1-Set2="gimnz"。

(2)Set1= " 012oper4a6tion89",Set2="error data",

Set1∪Set2="adeinoprt",Setl ∩Set2="aeort",Set1-Set2="inp"。

1.5 实现提示

以有序链表表示集合。

  • 数据结构的选择和概要设计

为实现上述程序功能,应该以有序链表表示集合,因此需要两个抽象数据类型:有序表和集合。

2.1 有序表的抽象数据类型定义为:

ADT OrderedList

{

数据对象:D={ai|ai CharSet,i=1,2,3,...n}

数据关系:R1={<ai-1,ai>|ai-1,ai  D,ai-1<ai,i=1,2,...n}

基本操作:

InitList(&L)

操作结果:构造一个空的有序表L。

DestroyList(&L)

初始条件:有序表L已经存在。

操作结果:销毁有序表L。

Length(L)

初始条件:有序表L已经存在。

操作结果:返回有序表L的长度。

ListEmpty(L)

初始条件:有序表L已经存在。

操作结果:若有序表L为空表,返回True,否则返回False。

GetElem(L,pos)

初始条件:有序表L已经存在。

操作结果:若pos Length(L),则返回表中第pos哥数据元素。

LocateElem(L,e,&q)

初始条件:有序表L已经存在。

操作结果:若有序表L存在元素e,则q指示L中第一个值为e的元素的位置,并返回函数值TRUE,否则q指示第一个大于e的元素的前驱的位置,并返回函数值FALSE。

Append(&L,e)

初始条件:有序表L已经存在。

操作结果:在有序表L的末尾插入元素e

InsertAfter(&L,q,e)

初始条件:有序表L已经存在,q指示L中一个元素。

操作结果:在有序表L中q指示的元素之后插入元素e。

bianli(q,visit())

初始条件:有序表L已经存在,q指示L中第一个元素。

操作结果:依次对L中q指示的元素开始的每个元素调用函数visit()。

}ADT OrderList

2.2 集合的抽象数据类型为:

ADT Set

{

数据对象:D={ai|ai为小写字母且互不相同,i,2,...n}

数据关系:R1={}

基本操作:

Createset(&T,Str)

初始条件:Str为字符串

操作结果:生成一个由Str中小写字母构成的集合T。

Destoryset(&T)

初始条件:集合T已经存在。

操作结果:销毁集合T的结构。

UnionSet(&T,S1,S2)

初始条件:集合S1和S2都存在。

操作结果:生成一个由S1和S2的差集构成的集合T。

Printset(T)

初始条件:集合T已经存在。

操作结果:按字母次序顺序显示集合T的全部元素。

}AND Set

2.3 程序组成

本程序包含四个模块:

  1. 结点结构单元模块——定义有序表的结点结构;

(2)有序表单元模块——实现有序表的抽象数据类型;

(3)集合单元模块——实现集合获得抽象数据类型;

(4)主程序模块

(5)int main(){

初始化;

构造集合 1;

构造集合 2;

if(接收命令){

处理命令

}退出

2.4 模块流程图

图2.1 系统模块流程图

图2.2 函数调用流程图

图2.3 主菜单流程图

图2.4 用户操作流程图

2.5 结构体设计

typedef struct SET{

char *elem;

int size;

int length;

}set;

  • 详细设计和编码

3.1 源代码

#include<iostream>

using namespace std;

#define OK 1

#define ERROR 0

typedef int Status;

typedef char ElemType;

//定义线性链表

typedef struct LNode

{

    ElemType data;

    struct LNode *next; 

}LNode, *LinkList;

//初始化操作

Status InitList(LinkList &L)

{

//构造一个空的单链表L

    L=new LNode;

    L->next=NULL;

    return OK;

}

//存储输入的字符串

Status cun_chu(ElemType *ch,int &length)

{

    length=0;

    ch[length]=getchar();

    length=1;

    ch[1000];

    while(true)

    {

       ch[length++]=getchar();

       if(ch[length -1 ]=='\n')

       {

           break;

       }

    }

    return OK;

}

//存储集合

Status Creat(LinkList &L)

{

    //初始化链表

    InitList(L);

    L = new LNode;

    L->next=NULL;

    LinkList r = L;

    int length;

    ElemType ch[1000];

    cun_chu(ch,length);

    for(int i=0;i<length;i++)

    {

       if(ch[i]<97 || ch[i]>122)

       {

           continue;

       }

       LinkList p = new LNode;

       p->data = ch[i];

       r->next = p;

       r=p;

     }

     r->next = NULL;

     return OK;

 }

//返回一个集合的长度

Status Length(LinkList L)

 {

    int i=0;

    while(L->next != NULL)    //下一个结点不为空

     {

        i++;

        L=L->next;

      }

      return i;

  }

 

//对一个字母集合进行从小到大的排序

Status Sort(LinkList &L)

{

    LinkList p,q,n;

    int l=Length(L);

    if(l<2)     //集合中只有一个元素

    {

       return OK;

    }

    int flag=1;     //控制集合是否需要重新遍历

    for(int i=l-1;i>0&&flag==1;i--)

    {

       flag=0;

       p=L;

       q=p->next;     //若从头结点开始,指向第一个有data值的结点

       n=q->next;     //指向与其相邻的下一个结点

       for(int j=0;j<i;j++)

       {

           if(q->data > n->data)    //遍历集合,只要存在前一个结点的data值大于后一个就交换两个节点的位置,并使flag的值为1

           {

              flag=1;

              p->next=n;

              q->next=n->next;

              n->next=q;

              q=p->next;

              n=q->next;

            }

            p=q;

            q=n;

            n=n->next;

        }

     }

     return OK;

 }

//输出集合

Status bianli(LinkList L)

 {

    if(L->next == NULL)

    {

       cout << "NULL";

     }

     else

     {

        LinkList p=L->next;

        while(p!=NULL)

        {

           cout<<p->data;

           p=p->next;

        }

     }

     cout<<endl;

     return OK;

  }

 

//创建并排序集合

Status CreatSet(LinkList &L)

{

    Creat(L);      //存储集合

    Sort(L);       //将集合中的元素从小到大排序

    return OK;

 }

//集合的并运算

Status UnionSet(LinkList A,LinkList B,LinkList &C)

{

    InitList(C);     //初始化集合C

    LinkList i = A->next;     //指向集合A的第一个元素

    LinkList j = B->next;     //指向集合B的第一个元素

    LinkList k = C;

    while(i!=NULL && j!=NULL)    //两个集合都没有遍历完

    {

       if(i->data < j->data)    //集合A的元素小于B

       {

           if(k->data != i->data)    //集合A的该元素与并集中的上一个存入的元素不同,执行存入

           {

              k->next=i;

              k=i;

           }

           i=i->next;

       }

       else if(i->data > j->data)    //集合A的元素大于B

       {

           if(k->data != j->data)    //集合A的该元素与并集中的上一个存入的元素不同,执行存入

           {

              k->next=i;

              k=j;

           }

           j=j->next;

       }

       else    //集合A的元素等于B

       {

           if(k->data != j->data)    //集合A的该元素与并集中的上一个存入的元素不同,执行存入

           {

              k->next=j;

              k=j;

           }

           i=i->next;

           j=j->next;

       }

    }

    if(j!=NULL)   //集合A已经遍历结束,集合B没有,将集合B中剩下所有元素插入,并且是不重复插入

    {

       int m;

       if(k->data != j->data)   //确保并集中不插入重复元素

       {

           k->next=j;

           m=1;

       }

       j=j->next;

       if(j!=NULL && m==1)

       {

           k=k->next;

           m=0;

       }

     }

     if(i!=NULL)   //集合B已经遍历结束,集合A没有,将集合A中剩下所有元素插入,并且是不重复插入

    {

       int n;

       if(k->data != i->data)   //确保并集中不插入重复元素

       {

           k->next=i;

           n=1;

       }

       i=i->next;

       if(i!=NULL)

       {

           k=k->next;

           n=0;

       }

     }

     if(k->next != NULL)

     {

        k=k->next;

     }

     k->next = NULL;

     return OK;

 }

 //集合的交运算

 Status InterSet(LinkList A, LinkList B, LinkList C)

 {

    InitList(C);

    LinkList i = A->next;     //指向集合A的第一个元素

    LinkList j = B->next;     //指向集合B的第一个元素

    LinkList k = C;

    while(i != NULL && j!=NULL)

    {

       if(i->data < j->data)

       {

           i=i->next;

        }

       else if(i->data > j->data)

       {

           j=j->next;

       }

       else

       {

           if(k->data != i->data)

           {

              k->next = i;

              k=i;

           }

           i=i->next;

           j=j->next;

        }

     }

     k->next = NULL;

     return OK;

  }

 

//集合的差运算

Status DifferentSet(LinkList A,LinkList B,LinkList C)

{

    InitList(C);

    LinkList i = A->next;     //指向集合A的第一个元素

    LinkList j = B->next;     //指向集合B的第一个元素

    LinkList k = C;

    while(i != NULL && j!=NULL)  //如果集合A的元素比B的小,说明该元素之后也不会出现在B集合

    {

       if(i->data < j->data)

       {

           if(k->data != i->data)

           {

              k->next=i;

              k=i;

           }

           i=i->next;

        }

       else if(i->data > j->data)

       {

           j=j->next;

       }

       else     //避免集合中重复元素的影响

       {

           int n=0;

           j=j->next;

           if(i->next ==NULL)

           {

              i=i->next;

           }

           while(i!=NULL && i->next != NULL)

           {

              if(i->data == i->next->data)

              {

                  i=i->next->next;

                  n=1;

              }

              else

              {

                  if(n==0)

                  {

                     i=i->next;

                  }

                  break;

              }

           }

        }

     }

     if(i)

     {

        k->next = i;    //如果A有剩余,直接加进去

     }

     else k->next =NULL;

     return OK;

 }

//菜单界面

Status showMenu()

{

    cout<<"***********"<<endl;

    cout<<"***1、集合的并运算***"<<endl;

    cout<<"***2、集合的交运算***"<<endl;

    cout<<"***3、集合的差运算***"<<endl;

    cout<<"***0、退出***"<<endl;

    cout<<"***********"<<endl;

    return OK;

 }

//主函数

Status main()

{

    showMenu();

    while(1)

    {

       int select;

       cout<<"请输入要执行的指令数字:"<<endl;

       cin>>select;

       switch(select)

       {

           case 1:     //集合的并集

              cout<<"**集合的并运算**"<<endl;

              LinkList A;

              cout<<"请输入集合A:"<<endl;

              CreatSet(A);

              //bianli(A);

              LinkList B;

              cout<<"请输入集合B:"<<endl;

              CreatSet(B);

              //bianli(B);

              LinkList C;

              UnionSet(A,B,C);

              cout<<"集合的并运算结果为:"<<endl;

              bianli(C);

              break;

           case 2:      //集合的交集

              cout<<"**集合的交运算**"<<endl;

              LinkList D;

              cout<<"请输入集合A:"<<endl;

              CreatSet(D);

              //bianli(D);

              LinkList E;

              cout<<"请输入集合B:"<<endl;

              CreatSet(E);

              //bianli(E);

              LinkList F;

              InterSet(D,E,F);

              cout<<"集合的交运算结果为:"<<endl;

              bianli(F);

              break;

           case 3:     //集合的差集

              cout<<"**集合的差运算**"<<endl;

              LinkList G;

              cout<<"请输入集合A:"<<endl;

              CreatSet(G);

              //bianli(G);

              LinkList H;

              cout<<"请输入集合B:"<<endl;

              CreatSet(H);

              //bianli(H);

              LinkList I;

              DifferentSet(G,H,I);

              cout<<"集合的差运算结果为:"<<endl;

              bianli(I);

              break;

              break;

           case 0:     //退出

              cout<<"欢迎下次使用"<<endl;

              system("pause");

              return OK;

              break;

           default:

              break;

       }

    }

    system("pause");

    return OK;

 }

  • 上机调试过程

4.1 调试示例

集合 1={magazine}

集合 2={paper}

4.2 调试结果

图片3.1  程序运行结果图

4.3 调试分析

(1)由于对集合的三种运算的算法推敲不足,在有序链表类型的早期版本未设置尾指针,导致算法低效。

(2)刚开始时忽略了一些变量参数的标识”&”,使调试程序时费时不少。今后应重视确定参数的变量和赋值属性的区分和标识。

  • 用户使用说明

程序运行后会显示菜单,用户可以根据菜单号输入相对应的数字,(如果用户输入1,程序将对两个集合进行并集运算并输出相应结果,用户输入2,程序将对两个集合进行交集运算对输出需要结果,用户输入3,程序将对两个集合进行差集运算并输出相应的结果,用户输入0,则程序运行结束,退出系统。)待用户输入相应的菜单号后,程序会提示用户输入集合A和集合B,用户输入完成后按下回车键,程序就会将两个集合的运算结果输出在屏幕上。只要用户不输入0,便可以一直进行运算,且每次可以输入不同的集合。

参考文献

[1]严蔚敏.吴伟民.数据结构 C 语言版.北京.清华大学出版社,2018.6.

[2]数据结构课程设计.https://www.docin.com/p-235288754.html

[3]数据结构课程设计——集合的并,交和差的运算.

[4]谭浩强.C语言程序设计.清华大学出版社

[5]严蔚敏.数据结构(C语言版).清华大学出版社,1999.

[6]严蔚敏.吴伟民.数据结构题集(C语言版).清华大学出版社,2003.5.

[7]李春葆.数据结构教程.清华大学出版社,2005.1.

[8]Jan Harrington(著).陈博(译).面向对象C++数据结构.科学出版社,2005.2.

[9]史蒂芬·普拉达.C Primer Plus 第6版 中文版【M】.人民邮电出版社,2019

[10]史蒂芬·普拉达.C++ Primer Plus中文版【M】.人民邮电出版社,2019

[11]数据结构课程设计-集合的并交和差运算(23页)-原创力文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/555059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最全iOS 上架指南

一、基本需求信息。 1、苹果开发人员账户&#xff08;公司已经可以无需申请&#xff0c;需要开启开发者功能&#xff0c;每年99美元&#xff09; 2、开发好应用程序 二、证书 上架版本需要使用正式证书。 1、创建Apple Developer证书 2、上传证书Sign In - Apple 3、点击开发者…

pyqt5:py处理C语言格式数组和有符号数的转换(备忘录)

文章目录 1.问题&#xff1a;把下面的数组所表示的正弦波用曲线描绘出来。1.1 将C语言数组直接替换为py数组1.2 使用numpy读入数组1.3完整代码 2.从正弦波数据生成C数组2.1 正弦波数据2.2 负数转成16位带符号整型公式2.3 负数转成16位带符号整型 完整代码 3. 生成正弦波数据的代…

ASEMI代理英飞凌IPA65R650CE功率MOS管中文资料

编辑-Z IPA65R650CE是一款高性能功率晶体管&#xff0c;旨在满足现代电子应用日益增长的需求。这种先进的半导体器件提供了高效、低功耗和优异热性能的独特组合&#xff0c;使其成为广泛应用的理想选择&#xff0c;包括电源、电机驱动和可再生能源系统。 IPA65R650CE的主要功能…

失业五个月,终于有offer了!但这家公司的风评惨不忍睹,要接吗?

往年&#xff0c;程序员们找工作可以说是不怎么费力的&#xff0c;不少求职者还会比对几家offer&#xff0c;看薪酬、看加不加班、看通勤时间等等等等&#xff0c;最后选择自己最满意的那一家过去。 但是今年&#xff0c;情况确实完全不一样&#xff0c;用网友的话形容就是“往…

vs code ts运行、断点调试解决方案

序&#xff1a; 1、解决ts在vs code里直接运行&#xff0c;并在终端直接看结果 2、解决ts 断点调试问题&#xff08;博主这个调试算的上全网最简单的设置方法了&#xff09;。 3、ts-node : 无法加载文件 C:\Program Files\nodejs\ts-node.ps1,因为在此系统上禁去看这篇》ts-no…

Velocity模板与itextpdf联合生成pdf

pom <!-- velocity模板引擎 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency><!-- itext7html转pdf --><depende…

LeetCode刷题(ACM模式)-01数组

参考引用&#xff1a;代码随想录 注&#xff1a;每道 LeetCode 题目都使用 ACM 代码模式&#xff0c;可直接在本地运行&#xff0c;蓝色字体为题目超链接 0. 数组理论基础 数组&#xff08;array&#xff09;是存放在连续内存空间上的相同类型数据的集合&#xff0c;是一种复合…

【哪些人不适合学习云计算?看看有没有你!】

云计算作为是互联网技术革命的重要一员&#xff0c;也是区别于一般IT职业的。作为高级技工&#xff0c;不是谁都能学会&#xff0c;也不是谁都适合这个技术。优秀的云计算工程师能让技术成为炫耀的资本&#xff0c;玩得神乎其技&#xff0c;引得众人追捧。我想这也是大部分热爱…

Cam APP-HAL流程追踪之demo梳理

一、基础知识 1、Google官网的Cam流程如下图1 2、Cam的预览、拍照、录像是分开的 Cam的预览、拍照、录像是各自独立的-换句话说可以不开启预览拍照或者录像–后面代码会详细介绍&#xff1b;市场上的成品Cam应用&#xff0c;打开Cam后直接打开了预览&#xff0c;然后可以拍照…

【数据结构】线性表之栈、队列

前言 前面两篇文章讲述了关于线性表中的顺序表与链表&#xff0c;这篇文章继续讲述线性表中的栈和队列。 这里讲述的两种线性表与前面的线性表不同&#xff0c;只允许在一端入数据&#xff0c;一段出数据&#xff0c;详细内容请看下面的文章。 顺序表与链表两篇文章的链接&…

最新社区论坛小程序源码 含流量主功能+前后端+部署搭建教程

分享一个社区论坛小程序源码&#xff0c;含完整前后端代码包和详细的部署搭建教程&#xff0c;做地方运营很适合&#xff0c;集成了流量主功能&#xff0c;一键轻松开启。 系统功能一览&#xff1a; 广场管理&#xff1a;广场列表&#xff0c;圈子列表&#xff0c;圈子审核 帖…

CE作业(4)

一、准备前提 服务端 客户端 ; 关闭防火墙systemctl stop firewalld 关闭selinux setenforce 0 提供DNS服务的软件叫bind&#xff0c;服务名是named 一、正向解析&#xff1a; 1.装包 yum install bind -y 2.配置服务 vim /etc/named.conf #监听53号端口 #访问的是本…

​数据库原理及应用上机(实验三 SQL数据查询)

✨作者&#xff1a;命运之光 ✨专栏&#xff1a;数据库原理及应用上机实验 ​ 目录 ✨一、实验目的和要求 ✨二、实验内容及步骤 ✨三、实验结果 ✨四、附加练习 ✨五、实验总结 &#x1f353;&#x1f353;前言&#xff1a; 数据库原理及应用上机实验报告的一个简单整理…

用别人的钱创咖啡的业,戴威与陆正耀殊途同归?

文 | 新熔财经 作者 | 和花 近四年来&#xff0c;ofo退押一事没有出现任何明显的转机&#xff0c;但ofo创始人戴威却已经在海外大张旗鼓地开启了名为About Time Coffee的新创业项目。 当“ofo创始人戴威再次创业”的消息登上微博热搜&#xff0c;收获的几乎都是“还钱”的征…

字符串按规则生成字典

带数字的字符串以数字为key倒序生成字典&#xff0c;字符串列表按其元素索引为key倒序生成字典。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简…

实验室云检验信息系统(云LIS源码)

一、区域云LIS系统概述&#xff1a; 区域云LIS平台源码&#xff0c;系统完全采用B/S架构模式&#xff0c;扩展性强。整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。 云LIS系统为实验室服务对象提供检验申请、采集标本、结果查…

【IDEA使用码云教程】

IDEA使用码云教程 一、下载、安装git二、配置Gitee插件三、克隆项目四、上传项目五、推送项目六、更新项目 一、下载、安装git 1.打开git官网&#xff0c;选择你的操作系统 官网下载地址&#xff1a;https://git-scm.com/downloads 2.根据你的系统位数选择相应的版本下载 系统…

frp+nginx+xposed搭建xp模块集群

frpcnginxxposed搭建xp模块集群 前言实现逻辑配置内网穿透实现负载均衡 前言 为了能够稳定的采集一些app的详情页数据&#xff0c;就得借助xposed&#xff0c;xposed跟NanoHTTPD配合使用就可以在手机端开启接口服务&#xff0c;直接调用手机端的接口就能获取我们想要的数据&am…

【机器学习】线性模型

文章目录 第三章&#xff1a;线性模型一、线性回归模型1.1、线性回归模型1.2、求解线性回归模型&#xff08;时刻要分清维度&#xff09;1.3、多输出线性回归模型 二、线性分类模型2.1、判别函数2.2、概率判别模型2.3、概率生成模型 第三章&#xff1a;线性模型 一、线性回归模…

怎么把视频压缩到500m以下?

如何把视频压缩到500m以下&#xff1f;视频文件通常是非常大的&#xff0c;特别是高清视频或超高清视频&#xff0c;因此压缩可以帮助将视频文件大小减小&#xff0c;在有限的存储空间中存储更多的视频文件。较大的视频文件在上传和下载时需要较长时间&#xff0c;而压缩视频文…