1、第 14章 C语言程序设计实例 第第 14章章 C语言程序设计实例语言程序设计实例 实例一实例一 成绩处理程序成绩处理程序实例二实例二 电子词典程序电子词典程序实例三实例三 野人渡河程序野人渡河程序第 14章 C语言程序设计实例 实例一实例一 成绩处理程序成绩处理程序 1.问题描述问题描述 进行若干个学生、若干门课程的成绩处理,要求计算:(1)每门课程的平均分和方差。(2)每个学生的总分、平均分及方差。(3)按总分对学生由高分到低分排序。第 14章 C语言程序设计实例 2.数据说明数据说明 (1)学生人数假定不超过1000人,课程门数假定不超过30门,分别用符号常量N、M描述。(2)实际学生人
2、数、实际课程门数分别用整型量n、m描述。(3)M门课程名称用二维字符数组sname描述。(4)学生数据考虑学号num、姓名name、M门课程成绩,用结构体stt描述。M门课程成绩用一维数组score描述。N个学生数据用结构体数组sta描述。第 14章 C语言程序设计实例 (5)每门课程的平均分和方差分别用一维实型数组avs1、sus1描述。(6)每个学生的总分、平均分及方差分别用一维实型数组total、avs2和实型量sus2描述。(7)排序结果引入一序号数组sort保存。以上变量定义为全局变量,同时利用这些变量在函数之间传递数据。(8)数据源文件、处理结果文件分别用字符指针变量ps、pt与文
3、件指针变量fps、fpt描述。第 14章 C语言程序设计实例 (9)引入中间整型变量i、j、k,i用于循环中控制学生,j用于循环中控制课程,k对应总分最高的学生序号。(10)数据源文件前面存放学生实际学生人数、实际课程门数与课程名称;处理结果文件中学生数据增加总分、平均分及名次,课程的平均分和方差、学生的平均分和方差存放于文件的最后。第 14章 C语言程序设计实例 3算法分析算法分析 (1)整个程序由主控模块main()、输入模块input()、每门课程的平均分和方差计算模块asfun()、每个学生的平均分及方差计算模块tasfun()、排序模块sortfun()、输出模块output()六个
4、模块组成。各模块之间顺序执行。(2)实际学生人数n、实际课程门数m、原始成绩数据由键盘输入或从磁盘数据文件读取。第 14章 C语言程序设计实例 (3)原始成绩数据由键盘输入时,将送磁盘文件SCORE.DAT保存。(4)方差计算公式为数据平方和的平均值减去数据平均值的平方。方差大,表示数据相互之间差别较大;方差小,表示数据相互之间差别较小。(5)排序采用选择排序方法,利用序号数组保存学生名次,无需交换数据。(6)处理结果与原始成绩数据合并后用另一磁盘文件STUDEN.DAT保存。第 14章 C语言程序设计实例 4.参考程序参考程序include stdio.hinclude math.hdefi
5、ne N 1000define M 30void input();void asfun();void tasfun();void sortfun();void output();第 14章 C语言程序设计实例 int n,m;struct sttint num;char*name;float scoreM;staN;char snameM16;float avs1M,svs1M;float totalN,avs2N,svs2;int sortN;第 14章 C语言程序设计实例 main()/*主控函数*/clrscr();input();asfun();tasfun();sortfun();o
6、utput();第 14章 C语言程序设计实例 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(请输入实际课程门数:);第 14章 C语言程序设计实例 scanf(%d,&m);if(n1000|m30)printf(数据无效!);exit(0);printf(请输入%d门课程名称:,m);for(j=
7、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);第 14章 C语言程序设计实例 ps=SCORE.DAT;/*送磁盘文件保存*/if(fps=fopen(ps,wb)=NULL)printf(文件建立错误!);exit(0);fwrite(&n,2,1,fps);fwrite(&m,2,1,fps);fwrite(sname,16,m,fps);fwri
8、te(sta,sizeof(struct stt),n,fps);fclose(fps);break;case F:/*数据从磁盘文件读取*/case f:第 14章 C语言程序设计实例 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(fps);break;第 14章 C语言程序设
9、计实例 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+)第 14章 C语言程序设计实例 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
10、=0;第 14章 C语言程序设计实例 for(j=0;jm;j+)totali+=sta i.scorej;avs2i=totali/n;ta+=avs2i;ts+=avs2i*avs2i;sus2=ts/n?(ta/n)*(ta/n);void sortfun()/*按总分排序*/int i,j,k;for(i=0;in;i+)k=i;for(j=i+1;jtotalk)k=j;sorti=k+1;第 14章 C语言程序设计实例 void output()/*输出数据*/int i,l,j;int is;char*pt;FILE*fpt;clrscr();/*输出数据送屏幕*/printf(
11、%d个学生%d门课程成绩数据如下:n);printf(学号 姓名 );for(j=0;jm;j+)printf(%16s,snamej);printf(|总分 平均分 名次n);for(i=0;in;i+)for(l=0;ln;l+)第 14章 C语言程序设计实例 if(sortl=i+1)is=l;printf(%8d%12s,stais.num,stais.name);for(j=0;jm;j+)printf(%16.2f,stais.scorej);printf(|%8.2f%8.2f%6dn,totalis,avs2is,sortis);printf(课程平均分 );for(j=0;j
12、m;j+)printf(%16.2f,avs1j);printf(n);printf(方差 );for(j=0;jm;j+)printf(%16.2f,sus1j);第 14章 C语言程序设计实例 printf(%16.2n,sus2);pt=STUDENT.DAT;/*输出数据送磁盘*/if(fpt=fopen(pt,wb)=NULL)printf(文件建立错误!);exit(0);fwrite(&n,2,1,fpt);fwrite(&m,2,1,fpt);fwrite(sname,16,m,fpt);for(i=0;ii;j-)strcpy(wordsj,wordsj-1);strcpy(
13、explsj,explsj-1);strcpy(wordsi,word);strcpy(explsi,expls);len+;第 14章 C语言程序设计实例 continue();void delete()/*删除*/char wordSTRLEN1;int i,j;flag=1;while(flag)printf(请输入待删除的单词:);第 14章 C语言程序设计实例 scanf(%s,word);i=search1(0,len-1,word);if(i=-1)printf(无此单词!n);else for(j=i;jlen-1;j+)strcpy(wordsj,wordsj+1);strc
14、py(explsj,explsj+1);len-;continue();第 14章 C语言程序设计实例 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);第 14章 C语言程序设计实例 strcpy(explsi,expl);continue();void quit(fil
15、e)/*退出*/char file;int i;FILE*fp;char ch;printf(是否存入词典(Y/N)?);第 14章 C语言程序设计实例 ch=getch();if(ch=Ych=y)if(fp=fopen(file,w)=NULL)printf(不能打开文件%s!n,file);exit(0);for(i=0;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;cha
16、r word;int m;第 14章 C语言程序设计实例 while(l0)l=m+1;else r=m-1;return(-1);int search2(l,r,word)/*查找插入位置*/int l,r;char word;第 14章 C语言程序设计实例 int m;while(l0)l=m+1;else r=m;return(l);第 14章 C语言程序设计实例 void continue()/*重复执行操作*/char ch;printf(继续执行吗(Y/N)?);ch=getch();if(ch=Y ch=y)flag=1;else flag=0;第 14章 C语言程序设计实例 5
17、.说明说明 (1)如果需增加单词及释义字串长度,应修改源程序中有关参数。(2)对单词除了释义外,还可增加发音、同义词、反义词等考虑。(3)流程图、简单技术文档亦请读者给出。(4)延伸考虑电子新华字典程序。第 14章 C语言程序设计实例 实例三实例三 野人渡河程序野人渡河程序 1问题描述 3个野人和3个传教士来到河边,打算乘一只船从右岸到左岸去。该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡过河去呢?本问题是一个简单的人工智能问题,是个典型的状态图搜索问题。这个问题还可以拓展为m个野人和n个传教士,而船一次可以装下r个人
18、的情况。第 14章 C语言程序设计实例 2参考程序参考程序#include#include#define maxloop 100 /最大层数#define pristnum 3 /传教士默认值#define slavenum 3 /野人默认值struct SPQ int sr,pr;/船运行一个来回后河右岸的野人、传教士的人数 int sl,pl;/船运行一个来回后河左岸的野人、传教士的人数 int ssr,spr;/回来(由左向右时)船上的人数 int sst,spt;/去时(由右向左时)船上的人数 int loop;/本结点所在的层数 第 14章 C语言程序设计实例 struct SPQ*
19、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 initiate();void releasemem();第 14章 C语言程序设计实例 void showresult();void addtoopened(
20、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)第 14章 C语言程序设计实例 recorder();releasemem();showresult();goon();else printf(无法找到符合条件的解);releasemem();goon();void initiate()int x;char choice;第 14章 C语
21、言程序设计实例 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;第 14章 C语言程序设计实例 unopened-sst=0;unopened-spt=0;un
22、opened-ssr=0;unopened-spr=0;unopened-loop=0;printf(题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。n);printf(该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人n);printf(就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡过河去呢?n);printf(n默认的n、m值皆为3n);for(;)第 14章 C语言程序设计实例 printf(n是否修改?(Y/N):);scanf(%s,&choice);choice=toupper(choice);if(choice=Y)printf(n请
23、输入传教士人数:);for(;)scanf(%d,&x);if(x0)unopened?pr=x;break;else printf(n输入值应大于0!n请重新输入);第 14章 C语言程序设计实例 printf(请输入野人人数:);for(;)scanf(%d,&x);if(x0)unopened?sr=x;break;else printf(n输入值应大于0!n请重新输入);break;if(choice=N)break;第 14章 C语言程序设计实例 int search()int flag;struct SPQ*ntx;/提供将要扩展的结点的指针 for(;)ntx=unopened;
24、/从待扩展链表中提取最前面的一个 if(ntx-loop=maxloop)return 0;addtoopened(ntx);/将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉 flag=stretch(ntx);/对ntx进行扩展,返回-1,0,1 if(flag=1)return 1;第 14章 C语言程序设计实例 int stretch(struct SPQ*ntx)int fsr,fpr;/在右岸上的人数 int fsl,fpl;/在左岸上的人数 int sst,spt;/出发时在船上的人数 int ssr,spr;/返回时船上的人数 struct SPQ*newnode;for
25、(sst=0;sst sr;fpr=ntx-pr;fsl=ntx-sl;fpl=ntx-pl;if(sst=fsr)&(2-sst)upnode=ntx;/保存父结点的地址以成链表newnode-nextnode=NULL;newnode-sr=0;newnode-pr=0;newnode-sl=opened?sr;newnode-pl=opened?pr;第 14章 C语言程序设计实例 newnode-sst=sst;newnode-spt=spt;newnode-ssr=0;newnode-spr=0;newnode-loop=ntx?loop+1;oend-nextnode=newnod
26、e;oend=newnode;openednum+;return 1;else if(fpr-fsr)*fpr=0)/判断是否满足传教士人数大于或等于野人人数fsl=fsl+sst;第 14章 C语言程序设计实例 fpl=fpl+spt;for(ssr=0;ssr=1;ssr+)/返回 int ffsl,ffpl;if(ssr=fsl)&(1-ssr)=0)/若符合条件则分配内存并赋值 int ffsr,ffpr;ffsr=fsr+ssr;ffpr=fpr+spr;newnode=(struct SPQ*)malloc(sizeof(spq);if(newnode=NULL)printf(n内
27、存不够!n);exit(0);第 14章 C语言程序设计实例 newnode-upnode=ntx;/保存父结点的地址 newnode-sr=ffsr;newnode-pr=ffpr;newnode-sl=ffsl;newnode-pl=ffpl;newnode-sst=sst;newnode-spt=spt;newnode-ssr=ssr;newnode-spr=spr;newnode-loop=ntx?loop+1;uend-nextnode=newnode;uend=newnode;unopenednum+;return 0;第 14章 C语言程序设计实例 void addtoopene
28、d(struct SPQ*ntx)unopened=unopened?nextnode;unopenednum?;if(openednum=0)oend=opened=ntx;oend?nextnode=ntx;oend=ntx;openednum+;第 14章 C语言程序设计实例 void recorder()int i,loop;struct SPQ*newnode;struct SPQ*ntx;loop=oend?loop;ntx=oend;resultnum=0;for(i=0;i sr=ntx-sr;ewnode-pr=ntx-pr;ewnode-sl=ntx-sl;ewnode-p
29、l=ntx-pl;ewnode-sst=ntx-sst;ewnode-spt=ntx-spt;ewnode-ssr=ntx-ssr;ewnode-spr=ntx-spr;ewnode-nextnode=NULL;tx=ntx-upnode;f(i=0)result=newnode;ewnode-nextnode=result;esult=newnode;esultnum+;第 14章 C语言程序设计实例 void releasemem()int i;struct SPQ*nodefree;for(i=1;i nextnode;free(nodefree);for(i=0;i nextnode;
30、free(nodefree);第 14章 C语言程序设计实例 void showresult()int i;int fsr,fpr;/在右岸上的人数int fsl,fpl;/在左岸上的人数struct SPQ*nodefree;printf(n);printf(%d个传教士和%d个野人渡河:,result?pr,result?sr);for(i=1;i nextnode;free(nodefree);printf(nnt左岸人数 船上人数及方向 右岸人数n);第 14章 C语言程序设计实例 printf(第%d轮n,i);fpl=result-pl-result-spt+result-spr;
31、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,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);第 14章 C语言程序设计实例 void goon()char choice;for(;)printf(n是否继续?(Y/N):);scanf(%s,&choice);choice=toupper(choice);if(choice=Y)break;if(choice=N)exit(0);第 14章 C语言程序设计实例 3运行结果运行结果 图14-1 野人渡河问题的解答 第 14章 C语言程序设计实例 4数据与算法分析数据与算法分析 本题的数据与算法分析以及问题拓展后的情况,请读者基于上面的程序,作为本章的练习去完成。