赵晓栋0921010424课程设计说明书.docx
- 文档编号:25201512
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:14
- 大小:135.72KB
赵晓栋0921010424课程设计说明书.docx
《赵晓栋0921010424课程设计说明书.docx》由会员分享,可在线阅读,更多相关《赵晓栋0921010424课程设计说明书.docx(14页珍藏版)》请在冰豆网上搜索。
赵晓栋0921010424课程设计说明书
中北大学
数据结构
课程设计说明书
学生姓名:
赵晓栋
学号:
0921010424
学院:
软件学院
专业:
软件工程
题目:
利用栈的表达式求值
成绩
指导教师
尹四清、薛海丽
2010年01月06日
1设计目的
利用栈求解表达式的值,设计出一个简洁、易操作的程序,供小学生做题并能给出分数:
1、建立试题库,程序随机从中抽取题目(其中涉及加减、乘除及带括号运算);
2、程序能够进行打分并保存分数,能够回顾历史;
3、随时能够退出程序。
2.设计内容和要求
利用栈求解表达式的值。
设计内容:
1)建立试题库文件,随机产生n个题目;
2)题目涉及加减乘除,带括弧的混合运算;
3)利用栈求解表达式的值;
4)随时可以退出;
5)保留历史分数,能回顾历史,给出与历史分数比较后的评价
基本要求:
1)系统功能的完善;
2)代码中有必要的注释
3.本设计所采用的数据结构
运用栈的结构体表示方法在程序中,例如我们定义两个栈:
字符栈和数字栈,分别来存放数字和字符,对于字符,比如算式中的“+”,“—”,“(”,“)”等的符号,如下:
typedefcharSElemType;//字符栈
typedefstruct{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefintSElemType1;//数字栈
typedefstruct{
SElemType1*base;
SElemType1*top;
intstacksize1;
}SqStack1;
4.功能模块详细设计
1.功能一:
栈求解一个表达式并将这个表达式翻译成一个机器指令序列;
2.功能二:
表达式求值;
3.功能三:
文件读写;
4.功能四:
作业评分;
5.功能五:
历史成绩本次成绩比较;
6.功能六:
输入“3”符号退出程序
4.1详细设计思想
程序代码如下,对相应的功能将做具体的说明:
1。
这是测试程序的开始,程序首先从文件中打开,读出试题,通过随机函数得出一个随机数来确定题的顺序,具体实现如下:
voidCeshi()
{
//inti=0;
intgrade=0;//测试成绩
printf("\t\t确定现在开始测试吗?
(y/n)");
charay;
cin>>ay;
if(ay=='n'){Clear();}
if(ay=='y')
{
printf("\n\n");
FILE*fp;
if((fp=fopen("shiti.txt","r"))==NULL)//打开试题文件
{
printf("cannotopenthisfile.\n");
exit(0);
}
srand(time(NULL));
intix=0;
intax[N];
for(ix=0;ix ax[ix]=rand()%10+1;//产生题目的随机号 for(ix=0;ix { intnum; num=ax[ix]-1; rewind(fp); fseek(fp,num*14,0); intj=0; charTimu[20]={'\0'}; Timu[j]=fgetc(fp); while(Timu[j]! ='#') { j++; Timu[j]=fgetc(fp); }//取题目 fclose(fp); 2。 题目的计算: 这一点将要用到两个定义的栈,既字符栈和数字栈,从数字栈和字符栈同步读取数据,但是,有一点要求必须注意,那就是运算符的优先级,故先通过优先级确认计算的顺序,然后来实现计算,这是一个难点,具体代码如下: //计算题目的答案 SqStackOPTR;SqStack1OPND;//OPTR为运算符栈,OPND为运算数栈 InitStack(OPTR); InitStack1(OPND);//初始化两个栈 Push(OPTR,'#');//'#'进入运算符栈 intjx=0; SElemTypex,theta,mx; SElemType1a,b,nx;//定义变量 charc; c=Timu[jx]; while(c! ='#'||gettop(OPTR,mx)! ='#')//接受到的字符非'#'且运算符栈栈顶元素非'#' { if(! Mrose2(c)){Push1(OPND,(c-48));jx++;c=Timu[jx];}//Mrose2(c)判断c是否是运算符,不是运算符则进运算数栈 else switch(Precede(gettop(OPTR,mx),c))//比较栈顶运算符与当前接收的运算符,得出优先权的高低 { case'<': Push(OPTR,c);jx++;c=Timu[jx];break; case'=': Pop(OPTR,x);jx++;c=Timu[jx];break; case'>': Pop(OPTR,theta);Pop1(OPND,b);Pop1(OPND,a);Push1(OPND,Mrose1(a,theta,b));break; } } //intnx; gettop1(OPND,nx);//得到答案 //printf("nx=%d\n",nx); DestroyStack(OPTR); DestroyStack1(OPND); 3。 试题的比较和确定答案的对错: 这个过程设计到比较和试题答案的保存,具体见程序的设计: //测试者开始做题 printf("\t\t◆"); intxh=0; while(Timu[xh]! ='#') { printf("%c",Timu[xh]); xh++; } printf("="); intbx; cin>>bx; //getchar(); if(bx==nx) { grade+=20; printf("\t\t(√,O(∩_∩)O)\n\n"); } else { grade+=0; printf("\t\t(×,o(╯□╰)o,答案是%d)\n\n",nx); } } fclose(fp); printf("\t\t你已完成答题! \n"); printf("\t\t你的得分为: %d\n",grade); chargo[3]; if(grade==0)go[0]=go[1]=go[2]=48; if(grade==100) { go[0]=49; go[1]=go[2]=48; } if(grade>0&&grade<100) { go[0]=48; go[2]=grade%10+48; go[1]=(grade-grade%10)/10+48; } FILE*fp1; if((fp1=fopen("grade.txt","ab+"))==NULL) { printf("cannotopenthisfile.\n"); exit(0); } time_tnow=time(0); char*ch1;charch2='\n'; ch1=asctime(localtime(&now)); if(fwrite(ch1,strlen(ch1),1,fp1)! =1) printf("filewriteerror! "); if(fwrite(&go,3,1,fp1)==NULL) printf("filewriteerror! "); if(fwrite(&ch2,1,1,fp1)==NULL) printf("filewriteerror! "); fclose(fp1); FILE*fp2; if((fp2=fopen("grade.txt","r"))==NULL) { printf("cannotopenthisfile.\n"); exit(0); } fseek(fp2,-33L,2); charch[3]; intge;//取上一次表示成绩的字符 for(ge=0;ge<3;ge++) ch[ge]=fgetc(fp2); inthuan;//上一次成绩 huan=(ch[0]-48)*100+(ch[1]-48)*10+(ch[2]-48); if(grade>huan)printf("\t\t你的上一次成绩为%d,你进步了! \n",huan); if(grade==huan)printf("\t\t你的上一次成绩为%d,你需要努力! \n",huan); if(grade \n",huan); system("pause"); Clear(); } } 4。 读取历史记录的文件: 这个过程涉及到文件的读取,比较容易实现,注意文件指针即可,具体代码见下: voidChaxun() { printf("\t\t你确定要查询历史成绩吗? (y/n)"); charchoose; cin>>choose; if(choose=='n'){Clear();} if(choose=='y') { printf("时间及成绩: \n"); FILE*fp; if((fp=fopen("grade.txt","r"))==NULL) { printf("cannotopenthisfile! \n"); exit(0); } charch; while(! feof(fp)) { ch=fgetc(fp); printf("%c",ch); } printf("\n"); } printf("\t\t查询完成! \n"); system("pause"); Clear(); } 5。 补充一点,以上程序用到的头文件包括以下几个: #include #include #include #include #include #include #include #include 4.2核心代码 #defineOK1 #defineERROR0 #defineSTACK_INIT_SIZE100 #defineSTACKINCREMENT10 #defineOVERFLOW-2 #defineN5 typedefintStatus; typedefcharSElemType;//字符栈 typedefstruct{ SElemType*base; SElemType*top; intstacksize; }SqStack; typedefintSElemType1;//数字栈 typedefstruct{ SElemType1*base; SElemType1*top; intstacksize1; }SqStack1; StatusInitStack(SqStack&s);//构造空栈 StatusDestroyStack(SqStack&s);//销毁栈 StatusGetTop(SqStacks,SElemType&e); StatusPush(SqStack&s,SElemTypee); StatusPop(SqStack&s,SElemType&e); gettop(SqStacks,SElemType&e); IsNum(charc);//判断是否数字字符 charPrecede(chara,charb);//比较栈顶算符与当前算符的优先级 intMrose1(inta,chartheta,intb); intMrose2(charc); StatusInitStack1(SqStack1&s);//构造空栈 StatusDestroyStack1(SqStack1&s);//销毁栈 StatusGetTop1(SqStack1s,SElemType1&e); StatusPush1(SqStack1&s,SElemType1e); StatusPop1(SqStack1&s,SElemType1&e); gettop1(SqStack1s,SElemType1&e); IsNum1(charc);//判断是否数字字符 charPrecede1(chara,charb);//比较栈顶算符与当前算符的优先级 intMrose11(inta,chartheta,intb); intMrose21(charc); voidMenuPrint(); voidClear(); voidCeshi(); voidChaxun(); 5、调试分析 1.开始新的练习 按照操作提示可以直接从题库中出题,出题后按要求给出得数,程序进行计算,屏幕见图: 当所有题库运行完毕后给出分数,如图所示: 2.查看历史记录: 记录里有所有的答题对错,和时间,如图所示…… 以上所有调试均在vs环境下成功,调试成功。 6、课程设计心得及存在问题 通过这次的课程设计,我学到了很多宝贵的知识,我们都知道,知识实践与实际才更有意义,我们通过自己所学的知识,编写出一些简单的程序,使得我们对编程的热情大大的提高。 看着自己的劳动成果,我们都有一种优越感,一种自豪感。 虽然看到了成果,但是我们也看到了不足的地方,我们所学的知识还不足以对付所有的问题,在不断编程,调试的过程中,通过观摩别人的程序,认真琢磨,总结,把别人的只是转化为自己的知识,从问题中找答案,调动自己主动学习的积极性和热情,比如在程序中看到的system(“pause”),rand(),等函数的应用,这都是通过自学及看别人的方法总结并使用而实现的。 通过这次的设计,我明白了,掌握扎实的知识功底的重要性和迫切性,因此,我认为这次的课程设计给我带来巨大的收获,尤其是思想上的收获。 以上为本人课程设计的感悟与总结,谢谢^_^
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 赵晓栋 0921010424 课程设计 说明书