集合运算.docx

上传人:b****8 文档编号:11445461 上传时间:2023-03-01 格式:DOCX 页数:16 大小:24.26KB
下载 相关 举报
集合运算.docx_第1页
第1页 / 共16页
集合运算.docx_第2页
第2页 / 共16页
集合运算.docx_第3页
第3页 / 共16页
集合运算.docx_第4页
第4页 / 共16页
集合运算.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

集合运算.docx

《集合运算.docx》由会员分享,可在线阅读,更多相关《集合运算.docx(16页珍藏版)》请在冰豆网上搜索。

集合运算.docx

集合运算

计算机学院教学实验报告

课程名称

高级程序语言实验

成绩

教师签名

实验名称

集合基本运算

实验序号

实验日期

姓名

学号

专业

年级-班

1、实验目的及实验内容

(本次实验所涉及并要求掌握的知识;实验内容;必要的原理分析)

小题分:

1.问题描述

【问题描述】

编写一个能演示执行两个集合之间的并、交和差运算结果的程序。

【基本要求】

1)两个集合中的元素为长度不同的字符串,字符串中可包含大小写字符和数字字符,

2)程序以用户的输入数据建立集合,然后执行集合运算,分别输出结果

2.问题涉及到的知识

单链表的建立

排序算法

有序链表的合并

字符的输入

3.解决思路原理

1)输入字符,头插法建立链表

2)利用冒泡排序对链表进行排序,建立有序链表

3)将有序链表A和B进行合并成链表C后,删去相同的字符,实现集合的并运算

4)对有序链表A中每个元素进行检查,求有序链表A和B中相同的字符,实现集合的交运算

5)对有序链表A中每个元素进行检查,删去与B中字符相同的部分,实现集合的减运算

2、实验环境及实验步骤

(本次实验所使用的器件、仪器设备等的情况;具体的实验步骤)

小题分:

1.运行平台

DevC++5.11

2.实验步骤

1)查阅资料,对集合的交、并、减运算算法的一般实现方法进行大致的印象记忆

2)分析问题,分析需要的函数功能,进行模块划分

3)分析合适的数据结构,确定合适的函数返回类型

4)翻阅《数据结构》和《高级程序设计语言》检验设想的正确与否,并参考书上的实例,确定主要算法

5)进行编程

6)调试,查阅资料,修改

7)撰写实验报告,反思实验的不足

3、实验过程分析

(详细记录实验过程中发生的故障和问题,进行故障分析,说明故障排除的过程及方法。

根据具体实验,记录、整理相应的数据表格、绘制曲线、波形等)

小题分:

1.实验过程

问题:

1)对函数的传递功能不明确,导致无法成功地将数据传递下去

2)没有考虑运行效率,导致算法性能不强,连用if语句,造成程序无法顺利运算

3)没有及时释放链表内存,造成内存泄漏

4)对集合的减运算没有清晰的认识,造成减运算输出错误

5)对链表的结构不清晰,在输出链表时,漏掉头或尾数据

6)不能自动滤去非法字符(如空格、阿拉伯数字等)。

7)刚开始时曾忽略了一些变量参数的标识”&”,使调试程序浪费时间不少。

今后应重视确定参数的变量和赋值属性的区分和标识

8)格式不统一,阅读起来不流畅

解决措施:

1)翻查资料,询问同学,加深对链表的理解

2)将IF语句的判断条件转化成其他语句,实现对其判断

3)运行结果不正确时,对算法进行重复思考,寻找出正确的解决途径

2.代码主体部分

voidreaddata(LinkList*&L);//定义输入集合函数,头插法建链表

voidSortList(LinkList*&La);//对链表排序

voidDeleteSame(LinkList*&La);//删去链表中相同的节点

voidadd(LinkList*La,LinkList*Lb,LinkList*Lc);//合并有序链表La和Lb

voidintersection(LinkList*La,LinkList*Lb,LinkList*Lc);//对有序链表La和Lb求交集

voidsub(LinkList*La,LinkList*Lb);//求有序链表La减有序链表Lb

intmain();

3.数据结构分析

有序单链表

结构体

typedefstructLinkNode

{

chardata;

structLinkNode*next;

}LinkList;

4.运行结果

4、实验结果总结

(对实验结果进行分析,完成思考题目,总结实验的新的体会,并提出实验的改进意见)

小题分:

1.复杂度分析

时间复杂度O(n*n)

空间复杂度O

(1)

2.运行效率

指针需要进行动态内存分配以及及时的释放链表,在没有及时的释放内存的情况下,时而造成程序的异常,但是整体而言,程序运行速度较快

3.改进意见

1)排序算法空间复杂度小,但是并没有对冒泡排序进行优化,不适合大数据,可采用希尔排序等其他排序方式;

2)及时释放链表内存

3)从《计算机组成原理》的角度去看代码的写成,分支语句不能进行多次的重复,会造成汇编时的不便

#include

#include

typedefstructLinkNode

{

chardata;

structLinkNode*next;

}LinkList;

voidreaddata(LinkList*&L);//定义输入集合函数,头插法建链表

voidSortList(LinkList*&La);//对链表排序

voidDeleteSame(LinkList*&La);//删去链表中相同的节点

voidadd(LinkList*La,LinkList*Lb,LinkList*Lc);//合并有序链表La和Lb

voidintersection(LinkList*La,LinkList*Lb,LinkList*Lc);//对有序链表La和Lb求交集

voidsub(LinkList*La,LinkList*Lb);//求有序链表La减有序链表Lb

intmain()

{

intx=0;

LinkList*La,*Lb,*Lc;

La=(LinkList*)malloc(sizeof(LinkList));

La->next=NULL;

Lb=(LinkList*)malloc(sizeof(LinkList));

Lb->next=NULL;

Lc=(LinkList*)malloc(sizeof(LinkList));

Lc->next=NULL;

printf("请输入一个字符串集合A(可包含数字)以!

结尾\n");

readdata(La);

printf("\n");

printf("集合A排序结果是");

SortList(La);

printf("\n\n");

printf("请再输入一个字符串集合B(可包含数字)以!

结尾\n");

readdata(Lb);

printf("\n");

printf("集合B排序结果是");

SortList(Lb);

A:

printf("1.并集2.交集3.差集4.结束x.重新运算\n");

do{

printf("请选择序号\n");

scanf("%d",&x);

switch(x)

{

case1:

add(La,Lb,Lc);//调用并集函数

Lc->next=NULL;

break;

case2:

intersection(La,Lb,Lc);//调用交集函数

Lc->next=NULL;

break;

case3:

sub(La,Lb);//调用差集函数

Lc->next=NULL;

break;

case4:

break;

default:

gotoA;

}

}while(x!

=4);

system("PAUSE");

return0;

}

voidreaddata(LinkList*&L)//定义输入集合函数,头插法建链表

{

LinkList*p;

chartmp;

scanf("%c",&tmp);

while(tmp!

='!

')

{

p=(LinkList*)malloc(sizeof(LinkList));

p->data=tmp;

p->next=L->next;

L->next=p;

scanf("%c",&tmp);

}

p=L->next;

while(p!

=NULL)

{

printf("%c",p->data);

p=p->next;

}

printf("\n");

}

voidcreate(charstr[],LinkList*&L)//采用尾插法建立有序链表

{

LinkList*s,*r;

inti;

r=L;

for(i=0;str[i]!

='\0';i++)

{

s=(LinkList*)malloc(sizeof(LinkList));

s->data=str[i];

r->next=s;

r=s;

}

r->next=NULL;

}

voidSortList(LinkList*&La)//对链表排序

{

LinkList*p;

LinkList*pre,*q;

p=La->next->next;

La->next->next=NULL;

while(p!

=NULL)//冒泡排序

{

q=p->next;

pre=La;

while(pre->next!

=NULL&&pre->next->datadata)

pre=pre->next;

p->next=pre->next;

pre->next=p;

p=q;

}

p=La->next;

while(p!

=NULL)

{

printf("%c",p->data);

p=p->next;

}

printf("\n");

}

voidDeleteSame(LinkList*&La)//删去链表中相同的节点

{

LinkList*p,*q;

p=La->next;

charc1,c2;

while(p->next!

=NULL)

{

c1=p->data;

c2=p->next->data;

if(c1==c2)//如果有相同的节点,则删去其中一个

{

q=p->next;

p->next=q->next;

free(q);

}

p=p->next;

}

}

voidadd(LinkList*La,LinkList*Lb,LinkList*Lc)//合并有序链表La和Lb

{

LinkList*r,*s,*pc;

LinkList*pa=La->next;

LinkList*pb=Lb->next;//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点

r=Lc;//r始终指向Lc的尾节点

while(pa!

=NULL&&pb!

=NULL)

{

if(pa->datadata)

//取较小者La中的元素,将pa链接在pc的后面,pa指针后移

{

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pa->data;

r->next=s;r=s;

pa=pa->next;

}

elseif(pa->data>pb->data)

//取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移

{

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pb->data;

r->next=s;r=s;

pb=pb->next;

}

else

{

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pb->data;

r->next=s;r=s;

pb=pb->next;

pa=pa->next;

}

}

while(pa!

=NULL)

{

/*if(pa->data>'z'||pa->data<'A'||pa->data<'a'||pa->data>'Z')

pa=pa->next;*/

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pa->data;

r->next=s;r=s;

pa=pa->next;

}

while(pb!

=NULL)

{

/*if(pb->data>'z'||pb->data<'A'||pb->data<'a'||pb->data>'Z')

pb=pb->next;*/

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pb->data;

r->next=s;r=s;

pb=pb->next;

}

r->next=NULL;

DeleteSame(Lc);

pc=Lc->next;

printf("并集为\n");

while(pc!

=NULL)

{

printf("%c",pc->data);

pc=pc->next;

}

printf("\n");

}

voidintersection(LinkList*La,LinkList*Lb,LinkList*Lc)//对有序链表La和Lb求交集

{

LinkList*pa=La->next;

LinkList*pb=Lb->next;

LinkList*r,*s,*pc;//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点

r=Lc;//r始终指向Lc的尾节点

while(pa!

=NULL&&pb!

=NULL)

{

if(pa->data==pb->data)

{

s=(LinkList*)malloc(sizeof(LinkList));

s->data=pa->data;

r->next=s;r=s;

pa=pa->next;

}

elseif(pa->data>pb->data)

pb=pb->next;

else

pa=pa->next;

}

r->next=NULL;

DeleteSame(Lc);

pc=Lc->next;

printf("交集为\n");

while(pc!

=NULL)

{

printf("%c",pc->data);

pc=pc->next;

}

printf("\n");

}

voidsub(LinkList*La,LinkList*Lb)//求有序链表La减有序链表Lb

{

LinkList*pa,*pb,*apre;

chare;

intflag;

pa=La;

apre=La;

while(pa!

=NULL)//遍历链表La中的每一个元素

{

flag=0;

e=pa->data;

pb=Lb;//对La中的每一个元素e,都从Lb的表头开始查找

while(pb!

=NULL)

{

if(pb->data==e)//若La中的元素Lb也有,则在La中删除该元素

{

if(pa==La)//pa是表头

{

La=pa->next;

apre=pa->next;

pa=pa->next;

flag=1;

}

elseif(pa->next==NULL)//pa是表尾

{

pa=NULL;

apre->next=pa;

flag=1;

}

else//非表头元素和表尾元素

{

apre->next=pa->next;

pa=pa->next;

flag=1;

}

break;

}

elsepb=pb->next;

}

if(flag==0)

{

apre=pa;

pa=pa->next;

}

}

printf("两集合之差为(前面的字符集合减去后面的字符集合)\n");

pa=La;

while(pa!

=NULL)

{

printf("%c",pa->data);

pa=pa->next;

}

printf("\n");

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 财会金融考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1