C语言课件第14章.ppt

上传人:sccc 文档编号:5385183 上传时间:2023-07-02 格式:PPT 页数:72 大小:239.51KB
返回 下载 相关 举报
C语言课件第14章.ppt_第1页
第1页 / 共72页
C语言课件第14章.ppt_第2页
第2页 / 共72页
C语言课件第14章.ppt_第3页
第3页 / 共72页
C语言课件第14章.ppt_第4页
第4页 / 共72页
C语言课件第14章.ppt_第5页
第5页 / 共72页
点击查看更多>>
资源描述

《C语言课件第14章.ppt》由会员分享,可在线阅读,更多相关《C语言课件第14章.ppt(72页珍藏版)》请在三一办公上搜索。

1、第 14章 C语言程序设计实例,实例一 成绩处理程序实例二 电子词典程序实例三 野人渡河程序,实例一 成绩处理程序,1.问题描述 进行若干个学生、若干门课程的成绩处理,要求计算:(1)每门课程的平均分和方差。(2)每个学生的总分、平均分及方差。(3)按总分对学生由高分到低分排序。,2.数据说明(1)学生人数假定不超过1000人,课程门数假定不超过30门,分别用符号常量N、M描述。(2)实际学生人数、实际课程门数分别用整型量n、m描述。(3)M门课程名称用二维字符数组sname描述。(4)学生数据考虑学号num、姓名name、M门课程成绩,用结构体stt描述。M门课程成绩用一维数组score描述

2、。N个学生数据用结构体数组sta描述。,(5)每门课程的平均分和方差分别用一维实型数组avs1、sus1描述。(6)每个学生的总分、平均分及方差分别用一维实型数组total、avs2和实型量sus2描述。(7)排序结果引入一序号数组sort保存。以上变量定义为全局变量,同时利用这些变量在函数之间传递数据。(8)数据源文件、处理结果文件分别用字符指针变量ps、pt与文件指针变量fps、fpt描述。,(9)引入中间整型变量i、j、k,i用于循环中控制学生,j用于循环中控制课程,k对应总分最高的学生序号。(10)数据源文件前面存放学生实际学生人数、实际课程门数与课程名称;处理结果文件中学生数据增加总

3、分、平均分及名次,课程的平均分和方差、学生的平均分和方差存放于文件的最后。,3算法分析(1)整个程序由主控模块main()、输入模块input()、每门课程的平均分和方差计算模块asfun()、每个学生的平均分及方差计算模块tasfun()、排序模块sortfun()、输出模块output()六个模块组成。各模块之间顺序执行。(2)实际学生人数n、实际课程门数m、原始成绩数据由键盘输入或从磁盘数据文件读取。,(3)原始成绩数据由键盘输入时,将送磁盘文件SCORE.DAT保存。(4)方差计算公式为数据平方和的平均值减去数据平均值的平方。方差大,表示数据相互之间差别较大;方差小,表示数据相互之间差

4、别较小。(5)排序采用选择排序方法,利用序号数组保存学生名次,无需交换数据。(6)处理结果与原始成绩数据合并后用另一磁盘文件STUDEN.DAT保存。,4.参考程序include stdio.hinclude math.hdefine N 1000define M 30void input();void asfun();void tasfun();void sortfun();void output();,int n,m;struct sttint num;char*name;float scoreM;staN;char snameM16;float avs1M,svs1M;float tot

5、alN,avs2N,svs2;int sortN;,main()/*主控函数*/clrscr();input();asfun();tasfun();sortfun();output();,void input()/*获取数据*/char ch;int i,j;char*ps;FILE*fps;printf(请选择数据源(K键盘输入 F磁盘文件读取):n);ch=getch();switch(ch)case K:/*数据从键盘输入*/case k:printf(请输入实际学生人数:);scanf(%d,&n);printf(请输入实际课程门数:);,scanf(%d,&m);if(n1000|m

6、30)printf(数据无效!);exit(0);printf(请输入%d门课程名称:,m);for(j=0;jm;j+)scanf(%s,snamej);for(i=0;in;i+)printf(请输入第%d个学生学号,姓名,%d门课程成绩:,i+1,m);scanf(%d%s,&stai.num,stai.name);for(j=0;jm;j+)scanf(%f,&stai.scorej);,ps=SCORE.DAT;/*送磁盘文件保存*/if(fps=fopen(ps,wb)=NULL)printf(文件建立错误!);exit(0);fwrite(&n,2,1,fps);fwrite(&

7、m,2,1,fps);fwrite(sname,16,m,fps);fwrite(sta,sizeof(struct stt),n,fps);fclose(fps);break;case F:/*数据从磁盘文件读取*/case f:,printf(“请输入数据文件名:”);scanf(%s,ps);if(fps=fopen(ps,rb)=NULL)printf(文件打开错误!);exit(0);fread(&n,2,1,fps);fread(&m,2,1,fps);fread(sname,16,m,fps);fread(sta,sizeof(struct stt),n,fps);fclose(

8、fps);break;,defautl:printf(数据源选择错误!);exit(0);void asfun()/*计算每门课程的平均分和方差*/int j;float tM,tsM;for(j=0;jm;j+)tj=0;tsj=0;for(i=0;in;i+),tj+=sta i.scorej;tsj+=sta i.scorej*sta i.scorej;avs1j=tj/n;sus1j=tsj/n-avs1j*avs1j;void tasfun()/*计算每个学生的总分、平均分和方差*/int i,j;float ta=0,ts=0;for(i=0;in;i+)totali=0;,for

9、(j=0;jtotalk)k=j;sorti=k+1;,void output()/*输出数据*/int i,l,j;int is;char*pt;FILE*fpt;clrscr();/*输出数据送屏幕*/printf(%d个学生%d门课程成绩数据如下:n);printf(学号 姓名);for(j=0;jm;j+)printf(%16s,snamej);printf(|总分 平均分 名次n);for(i=0;in;i+)for(l=0;ln;l+),if(sortl=i+1)is=l;printf(%8d%12s,stais.num,stais.name);for(j=0;jm;j+)prin

10、tf(%16.2f,stais.scorej);printf(|%8.2f%8.2f%6dn,totalis,avs2is,sortis);printf(课程平均分);for(j=0;jm;j+)printf(%16.2f,avs1j);printf(n);printf(方差);for(j=0;jm;j+)printf(%16.2f,sus1j);,printf(%16.2n,sus2);pt=STUDENT.DAT;/*输出数据送磁盘*/if(fpt=fopen(pt,wb)=NULL)printf(文件建立错误!);exit(0);fwrite(&n,2,1,fpt);fwrite(&m,

11、2,1,fpt);fwrite(sname,16,m,fpt);for(i=0;in;i+)fwrite(&stai,sizeof(struct stt),1,fpt);fwrite(&totali,4,1,fpt);fwrite(&avs2i,4,1,fpt);,fwrite(&sorti,2,1,fpt);fwrite(avs1,4,m,fpt);fwrite(&sus2,4,1,fpt);fclose(fpt);,5.几点说明(1)数据源文件可用字处理软件直接建立。(2)程序的实现可以不用数组,而用链表。(3)函数之间数据可改用参数传递。(4)处理结果还可考虑打印输出。(5)流程图请读者

12、画出。(6)所做的数据与算法分析可转化成本程序的简单技术文档。,实例二 电子词典程序,1.问题描述 在计算机中建立有限规模的电子英汉词典(文件),利用程序实现电子英汉词典的查找与增、删、改等维护。,2.数据说明(1)对单词和释义字符串长度的限定分别为不超过20个与40个字符,词条数限定为不超过1000条。(2)单词数组words,字符串数组。释义数组expls,字符串数组。词典中词条总数len,整型变量。(3)标志变量flag,在主函数中为0则执行菜单,为1则退出程序;在进入词典操作命令后,为1则继续执行同一命令,为0则退回到菜单。以上变量定义为全局变量。,(4)命令序号num,整型。在mai

13、n()函数中用于散转执行对应操作。(5)一维字符数组(字符串)word在lookup()函数中为待查单词,在insert()函数中为r待插入单词,在delete()函数中为待删除单词,在modify()函数中为待修改单词,在display()函数中为待显示单词。(6)一维字符数组(字符串)expl为待插入释义或待改成的释义。(7)在search1()和search2()中,正整数l,查找下限,形参;正整数r,查找上限,形参;正整数m,中点位置,计算得到。,3.算法分析,(1)执行该程序要求在磁盘上有一个词典文件,可使用任何中文编辑软件生成。其内容是每行对应一个词条,每词条包括用若干空格符分开两

14、个字符串,前一个是单词字符串(英文),后一个是释义字符串(中文),使用分号作为多个释义的分隔符(无空格)。事实上,即使该文件内无一词条,也可用本程序在线生成所需词典,但必须有一个已存在的合乎上述格式的,哪怕是空白的文件。,(2)采用菜单工作方式。在一个操作命令执行之后,程序询问是否继续执行该命令。如输入y或Y,则重复同一操作,不退回到菜单;如输入其它信息,则回到菜单等待另一次选择。仅当选择退出操作时,程序会询问是否将修改后的词典存盘,并根据用户的选择存盘或不存盘退出。,(3)除主函数之外,程序包含其它 11 个函数:input(file):从文件file中读入词典各词条的单词和释义分别到字串数

15、组words和expls中。对每个字符串长度进行检查,发现非法长度后会显示出错信息并退出程序。menu():显示控制菜单。lookup():查询一个单词的释义。insert():在词典中适当位置插入一个给定词条的单词和释义。delete():从词典中删去一个词条的单词和释义。modify():修改词典中给定单词的释义。display():显示词典中在给定单词前后的部分词条的单词和释义。,quit():在询问是否要存盘之后退出程序。search1(l,r,word):在单词数组words的1r位置中查找给定单词word的位置。查到,返回该位置;查不到返回-1。分别由lookup()、delete

16、()、modify()和display()调用。search2(1,r,word):在单词数组words的1r位置中查找给定单词word的插入位置。查到,返回该位置;查不到,不必插入,返回-1。分别由insert()和display()调用。continue():询问用户是否继续执行词典的操作。除了退出,查询、插入、删除、修改、显示均调用该函数。,4.参考程序,include stdio.hinclude string.hdefine MAXLEN 1000define STRLEN1 20define STRLEN2 40void menu();void input();void looku

17、p();void insert();void delete();void modify();void display();void quit();,int search1();int search2();void continue();char*wordsMAXLEN,*explsMAXLEN;int len,flag=0;main()/*主控函数*/char*file;int num;printf(请输入词典文件名:n);scanf(%s,file);input(file);while(!flag)menu();,scanf(%d,&num);switch(num)case 1:lookup

18、();break;case 2:insert();break;case 3:delete();break;case 4:modify();break;case 5:display();break;case 6:qiut(file);break;default:printf(选择错,按任一键返回菜单!);getch();,void input(file)/*读取词典*/char file;int i;FILLE*fp;char strSTRLEN1;if(fp=fopen(file,r)=NULL)printf(不能打开文件%s!,file);exit(0);i=0;fscanf(fp,%s,s

19、tr);while(!feof(fp),strcpy(wordsi,str);fscanf(fp,%s,explsi+);fscanf(fp,%s,str);len=i;fclose(fp);void menu()/*菜单*/clrscr();printf(电子词典程序n);printf(nn1-单词查询n);printf(2-增加词条n);,printf(3-删除词条n);printf(4-修改词条n);printf(5-显示词条n);printf(6-退出nnn);printf(nn请选择(16)n);void lookup()/*查找单词释义*/char wordSTRLEN1;int

20、i;flag=1;while(flag)printf(请输入查询单词:);scanf(%s,word);i=search1(0,len-1,word);,if(i=-1)printf(无此单词!n);else printf(%sn,explsi);continue();void insert()/*插入*/char wordSTRLEN1,explSTRLEN2;int i,j;flag=1;while(flag)printf(请输入待插入的单词和释义:);scanf(%s%s,word,expl);,i=search2(0,len,word);if(i=-1)printf(已有此单词!n);

21、else for(j=len;ji;j-)strcpy(wordsj,wordsj-1);strcpy(explsj,explsj-1);strcpy(wordsi,word);strcpy(explsi,expls);len+;,continue();void delete()/*删除*/char wordSTRLEN1;int i,j;flag=1;while(flag)printf(请输入待删除的单词:);,scanf(%s,word);i=search1(0,len-1,word);if(i=-1)printf(无此单词!n);else for(j=i;jlen-1;j+)strcpy

22、(wordsj,wordsj+1);strcpy(explsj,explsj+1);len-;continue();,void modify()/*修改*/char wordSTRLEN1,explSTRLEN2;int i;flag=1;while(flag)printf(请输入待修改的单词:);scanf(%s,word);i=search1(0,len-1,word);if(i=-1)printf(无此单词!n);else printf(输入新释义:);scanf(%s,expl);,strcpy(explsi,expl);continue();void quit(file)/*退出*/

23、char file;int i;FILE*fp;char ch;printf(是否存入词典(Y/N)?);,ch=getch();if(ch=Ych=y)if(fp=fopen(file,w)=NULL)printf(不能打开文件%s!n,file);exit(0);for(i=0;ilen;i+)fprintf(fp,%-20s%-40sn,wordsi,explsi);fclose(fp);,flag=1;void display()/*显示*/int i,i1,i2;char wordSTRLEN1;flag=1;while(flag)printf(请输入待显示的单词:);scanf(%

24、s,word);i=search1(0,len-1,word);,if(i=-1)i=search2(0,len,word);i1=i=8?i-8:0;i2=i=len-8?i+8:len-1;for(i=i1;i=i2;i+)printf(%-20s%-40sn,wordsi,explsi);continue();int search1(1,r,word)/*查找单词位置*/int l,r;char word;int m;,while(l0)l=m+1;else r=m-1;return(-1);int search2(l,r,word)/*查找插入位置*/int l,r;char word

25、;,int m;while(l0)l=m+1;else r=m;return(l);,void continue()/*重复执行操作*/char ch;printf(继续执行吗(Y/N)?);ch=getch();if(ch=Y ch=y)flag=1;else flag=0;,5.说明(1)如果需增加单词及释义字串长度,应修改源程序中有关参数。(2)对单词除了释义外,还可增加发音、同义词、反义词等考虑。(3)流程图、简单技术文档亦请读者给出。(4)延伸考虑电子新华字典程序。,实例三 野人渡河程序,1问题描述 3个野人和3个传教士来到河边,打算乘一只船从右岸到左岸去。该船的负载能力为两人。在任

26、何时候,如果野人人数超过传教士人数,野人就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡过河去呢?本问题是一个简单的人工智能问题,是个典型的状态图搜索问题。这个问题还可以拓展为m个野人和n个传教士,而船一次可以装下r个人的情况。,2参考程序#include#include#define maxloop 100/最大层数#define pristnum 3/传教士默认值#define slavenum 3/野人默认值struct SPQ int sr,pr;/船运行一个来回后河右岸的野人、传教士的人数 int sl,pl;/船运行一个来回后河左岸的野人、传教士的人数 int ssr,sp

27、r;/回来(由左向右时)船上的人数 int sst,spt;/去时(由右向左时)船上的人数 int loop;/本结点所在的层数,struct SPQ*upnode,*nextnode;/本结点的父结点和同层的下一个结点的地址 spq;int loopnum;/记录总的扩展次数int openednum;/记录已扩展节点个数int unopenednum;/记录待扩展节点个数int resultnum;struct SPQ*opened;struct SPQ*oend;struct SPQ*unopened;struct SPQ*uend;struct SPQ*result;void init

28、iate();void releasemem();,void showresult();void addtoopened(struct SPQ*ntx);int search();void goon();int stretch(struct SPQ*ntx);void recorder();void main()int flag;/标记扩展是否成功for(;)initiate();flag=search();if(flag=1),recorder();releasemem();showresult();goon();else printf(无法找到符合条件的解);releasemem();go

29、on();void initiate()int x;char choice;,uend=unopened=(struct SPQ*)malloc(sizeof(spq);if(uend=NULL)printf(n内存不够!n);exit(0);unopenednum=1;openednum=0;unopened-upnode=unopened;/保存父结点的地址以成链表unopened-nextnode=unopened;unopened-sr=slavenum;unopened-pr=pristnum;unopened-sl=0;unopened-pl=0;,unopened-sst=0;u

30、nopened-spt=0;unopened-ssr=0;unopened-spr=0;unopened-loop=0;printf(题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。n);printf(该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人n);printf(就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡过河去呢?n);printf(n默认的n、m值皆为3n);for(;),printf(n是否修改?(Y/N):);scanf(%s,printf(请输入野人人数:);for(;)scanf(%d,int search()int flag

31、;struct SPQ*ntx;/提供将要扩展的结点的指针 for(;)ntx=unopened;/从待扩展链表中提取最前面的一个 if(ntx-loop=maxloop)return 0;addtoopened(ntx);/将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉 flag=stretch(ntx);/对ntx进行扩展,返回-1,0,1 if(flag=1)return 1;,int stretch(struct SPQ*ntx)int fsr,fpr;/在右岸上的人数 int fsl,fpl;/在左岸上的人数 int sst,spt;/出发时在船上的人数 int ssr,sp

32、r;/返回时船上的人数 struct SPQ*newnode;for(sst=0;sst sr;fpr=ntx-pr;fsl=ntx-sl;fpl=ntx-pl;if(sst=fsr),fpr=fpr-spt;if(fpr=0),newnode-sst=sst;newnode-spt=spt;newnode-ssr=0;newnode-spr=0;newnode-loop=ntx?loop+1;oend-nextnode=newnode;oend=newnode;openednum+;return 1;else if(fpr-fsr)*fpr=0)/判断是否满足传教士人数大于或等于野人人数fs

33、l=fsl+sst;,fpl=fpl+spt;for(ssr=0;ssr=0)/若符合条件则分配内存并赋值 int ffsr,ffpr;ffsr=fsr+ssr;ffpr=fpr+spr;newnode=(struct SPQ*)malloc(sizeof(spq);if(newnode=NULL)printf(n内存不够!n);exit(0);,newnode-upnode=ntx;/保存父结点的地址 newnode-sr=ffsr;newnode-pr=ffpr;newnode-sl=ffsl;newnode-pl=ffpl;newnode-sst=sst;newnode-spt=spt;

34、newnode-ssr=ssr;newnode-spr=spr;newnode-loop=ntx?loop+1;uend-nextnode=newnode;uend=newnode;unopenednum+;return 0;,void addtoopened(struct SPQ*ntx)unopened=unopened?nextnode;unopenednum?;if(openednum=0)oend=opened=ntx;oend?nextnode=ntx;oend=ntx;openednum+;,void recorder()int i,loop;struct SPQ*newnode

35、;struct SPQ*ntx;loop=oend?loop;ntx=oend;resultnum=0;for(i=0;i=loop;i+)newnode=(struct SPQ*)malloc(sizeof(spq);if(newnode=NULL)printf(n内存不够!n);exit(0);,newnode-sr=ntx-sr;ewnode-pr=ntx-pr;ewnode-sl=ntx-sl;ewnode-pl=ntx-pl;ewnode-sst=ntx-sst;ewnode-spt=ntx-spt;ewnode-ssr=ntx-ssr;ewnode-spr=ntx-spr;ewno

36、de-nextnode=NULL;tx=ntx-upnode;f(i=0)result=newnode;ewnode-nextnode=result;esult=newnode;esultnum+;,void releasemem()int i;struct SPQ*nodefree;for(i=1;i nextnode;free(nodefree);for(i=0;i nextnode;free(nodefree);,void showresult()int i;int fsr,fpr;/在右岸上的人数int fsl,fpl;/在左岸上的人数struct SPQ*nodefree;print

37、f(n);printf(%d个传教士和%d个野人渡河:,result?pr,result?sr);for(i=1;i nextnode;free(nodefree);printf(nnt左岸人数 船上人数及方向 右岸人数n);,printf(第%d轮n,i);fpl=result-pl-result-spt+result-spr;fpr=result-pr-result-spr;fsl=result-sl-result-sst+result-ssr;fsr=result-sr-result-ssr;printf(传教士%8d%8dt spt,fpr);printf(野 人%8d%8dt sst

38、,fsr);printf(传教士%8d%8dt-t%8dn,result-pl,result-spr,result-pr-result-spr);printf(野 人%8d%8dt-t%8dn,result-sl,result-ssr,result-sr-result-ssr);printf(n全体传教士和野人全部到达对岸!);free(result);,void goon()char choice;for(;)printf(n是否继续?(Y/N):);scanf(%s,3运行结果,图14-1 野人渡河问题的解答,4数据与算法分析 本题的数据与算法分析以及问题拓展后的情况,请读者基于上面的程序,作为本章的练习去完成。,

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

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号