数据结构课程设计趣味算式.docx
- 文档编号:9036089
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:25
- 大小:228.12KB
数据结构课程设计趣味算式.docx
《数据结构课程设计趣味算式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计趣味算式.docx(25页珍藏版)》请在冰点文库上搜索。
数据结构课程设计趣味算式
信息科学与技术学院
数据结构课程设计报告
题目名称:
趣味算式(38)
学生姓名:
赵星标
学号:
20161008038
专业班级:
16计科一班
指导教师:
张丽
2018年1月10日
一、需求分析
1.程序概要
本程序面向的对象为初学四则运算小学生,重点解决小学生在学习四则运算过程中没有实际例题应用,学习过程枯燥无味没有成就感的问题
2.程序设计模块:
(1)主菜单模块
(2)更新试题库模块
(3)答题模块
(4)判题模块
(5)成绩比较模块
(6)退出模块
二、概要设计
为实现上述程序功能,应采用顺序存储结构存储算式,结合栈和队列,对拥有运算符优先级别之分的算式进行计算。
1.模块调用关系
模块间调用关系如图1.1所示
图1.1模块调用关系流程图
2.主菜单模块设计
主菜单模块是程序的“门面”,其作用是将程序的功能点展示给用户,并且根据用户的输入流反馈执行相应的模块跳转,其流程图如图1.2所示
图1.2主菜单模块流程图
3.更新题库模块设计
更新题库模块要做到清除数据文件“data.txt”文件中的内容,并且随机写入100道不重复带括号或者不带括号的四则运算的试题,其模块流程图如图1.3。
图1.3更新题库模块流程图
4.答题模块设计
此模块作为用户的主功能模块,是整个程序中最有意义的模块,答题模块要做到随机从数据文件(data.txt)中抽取10道题目并逐一显示,用户输入后调用判题模块进行判断题目正误,在题目更换过程中采用非阻塞形式判断用户有没有输入结束符,如果有则结束答题,给出评价后退出程序,没有输入结束符的显示完十道题目后正常判题,给出评价并返回主菜单,答题模块流程图如图1.4
图1.4答题模块流程图
5.判题模块设计
判题模块是趣味计算程序开发过程中最核心,代码量最大的部分,此部分采用栈为存储结构,中间采用了队列转存数据,采用递归的形式进行计算,先将括号内的内容递归下去,然后计算乘除运算,最后计算加减运算,判题模块流程图如图1.5所示
图1.5判题模块流程图
6.成绩比较模块设计
成绩比较模块主要完成历史记录与本次测试成绩的对比,并给出排名和等级,成绩比较模块流程图如图1.6
图1.6成绩比较模块流程图
7.退出模块设计
退出模块的作用是无论在程序的哪一个阶段只要调用此模块就中断程序并且退出程序,退出模块流程图如图1.7所示
图1.7退出模块流程图
三、详细设计
1.函数定义
voidfirst();//显示程序开始界面
voidfinish(intn);//比较历史函数并显示级别
doublecalculation(char*p);//计算表达式值
voidnewsubject();//更新题目
voidstart();//答题
voidmenu();//菜单显示
2.核心函数具体代码
2.1doublecalculation(char*p)//计算字符串表达式的值
{
queue
queue
stack
stack
doubletempsum=0;
for(inti=0;i { if(p[i]>='0'&&p[i]<='9') { tempsum=tempsum*10+p[i]-'0'; if(! (p[i+1]>='0'&&p[i+1]<='9')) { doubleque.push(tempsum); tempsum=0; } } else { if(p[i]=='(')//拆分括号内的字符串 { chartempstring[SIZE_OF_CHAR]; intsurel=i; while (1) { if(p[i]==')') break; i++; } intsurer=i; strcpy(tempstring,p); strcpy(&tempstring[surer],""); strcpy(tempstring,&tempstring[surel+1]); tempsum=calculation(tempstring);//递归调用求括号内的值 if(tempsum==ERROR_NUM) { returnERROR_NUM; } else { doubleque.push(tempsum); tempsum=0; } } else { if(p[i]=='+'||p[i]=='-'||p[i]=='*'||p[i]=='/') { charque.push(p[i]); } else { returnERROR_NUM; } } } } tempsum=doubleque.front(); doubleque.pop(); intsurefinish=0; while(! doubleque.empty())//求乘除运算部分代码 { chartempchar=charque.front(); charque.pop(); if(tempchar=='*') { tempsum=tempsum*doubleque.front(); doubleque.pop(); surefinish=1; } else { if(tempchar=='/') { if(doubleque.front()==0) { returnERROR_NUM; } else { tempsum=tempsum/doubleque.front(); doubleque.pop(); } surefinish=1; } else { dou_after.push(tempsum); tempsum=doubleque.front(); doubleque.pop(); cha_after.push(tempchar); surefinish=0; } } } dou_after.push(tempsum); while(! dou_after.empty())//通过栈和队列的转换调整元素的位置 { doubleque.push(dou_after.top()); dou_after.pop(); } while(! cha_after.empty()) { charque.push(cha_after.top()); cha_after.pop(); } while(! doubleque.empty()) { dou_after.push(doubleque.front()); doubleque.pop(); } while(! charque.empty()) { cha_after.push(charque.front()); charque.pop(); } while(! dou_after.empty()) { doubleque.push(dou_after.top()); dou_after.pop(); } while(! cha_after.empty()) { charque.push(cha_after.top()); cha_after.pop(); } doublereturnsum; returnsum=doubleque.front(); doubleque.pop(); while(! doubleque.empty())//计算加减的值 { if(charque.front()=='+') { returnsum+=doubleque.front(); doubleque.pop(); charque.pop(); } else { returnsum-=doubleque.front(); doubleque.pop(); charque.pop(); } } returnreturnsum; } 2.2voidnewsubject() { system("cls"); cout<<"是否生成题目? chartempch=''; while (1) { if(tempch=='Y'||tempch=='y') { cout<<"题目生成中"; break; } if(tempch=='N'||tempch=='n') { cout<<"三秒后返回上层目录"; Sleep(3000); return; } tempch=getch(); } inti=0;//显示进度条 for(i=1;i<=30;++i) { printf("-"); } fflush(stdout); for(i=1;i<=30;++i) { printf("\b"); } for(i=1;i<=30;++i) { printf(">"); fflush(stdout); Sleep(100); } printf("\n"); time_tts;//设置时间变量 srand((unsignedint)time(&ts));//设置时间的随机数种子 charcode[4]={'+','-','*','/'};//设置运算符号 FILE*fp; fp=fopen("data.txt","w"); for(inti=0;i<100;i++) { charsub_data[100]={'\0'};//保存一道题目的位置 intminnum=rand()%3;//生成括号位置 intmaxnum=minnum+1+rand()%(3-minnum); if(minnum==0&&maxnum==3) { minnum=maxnum=-1; } //minnum=maxnum=-1; for(intj=0;j<4;j++) { if(j==minnum) { sprintf(&sub_data[strlen(sub_data)],"(%d%c",rand()%10,code[rand()%4]); } else { if(j==maxnum) { sprintf(&sub_data[strlen(sub_data)],"%d)%c",rand()%10,code[rand()%4]); } else { sprintf(&sub_data[strlen(sub_data)],"%d%c",rand()%10,code[rand()%4]); } } } if(sub_data[strlen(sub_data)-1]<'0'||sub_data[strlen(sub_data)-1]>'9') { sub_data[strlen(sub_data)-1]=0; } if(calculation(sub_data)==ERROR_NUM)//如果生成的算式存在被除数为0的情况则重新生成 { i--; continue; } fprintf(fp,"%s\n",sub_data); sub_data[0]=0; } fclose(fp); cout<<"\n[题目生成成功]-三秒后自动返回\n"; Sleep(3000); } 2.3voidstart() { system("cls"); time_tts;//设置时间变量 intgrade=0; srand((unsignedint)time(&ts));//设置时间的随机数种子 cout<<"两秒后自动开始答题(结果四舍五入保留整数)"< Sleep(2000); system("cls"); FILE*fp; chara[100]; fp=fopen("data.txt","r"); for(inti=0;i<10;i++) { intj=1+rand()%10; doubleans; while(j--) { fscanf(fp,"%s",a); } cout< cin>>ans; doubletempsavea=calculation(a); if(ans==(tempsavea>0? (int)(0.5+tempsavea): (int)(tempsavea-0.5))) { grade++; cout<<"【正确】"< } else { cout<<"【错误】你的答案: "< "<<(tempsavea>0? (int)(0.5+tempsavea): (int)(tempsavea-0.5))<<"当前得分: "< } cout< getchar(); inttempi=20; while(tempi--) { if(kbhit()==1) { if(getch()==27) { finish(grade); getch(); exit(0); } } Sleep(100); } system("cls"); } system("cls"); finish(grade); } 四、调试分析 1.程序编写过程中遇到的问题 刚开始编写的时候没有考虑到括号的问题,编写完成之后发现题目要求中存在括号,所以浪费了一部分时间,后来一直在用int类型的变量来储存运算结果,后来发现了严重的bug,int类型的运算只能做整数运算会丧失很大的精度,不得已只能推翻重写,在后面的运算中又遇到了程序异常停止的问题,后经检查发现是没有考虑到除数为零的情况导致的运算错误,在后面又遇到了同一个字符串调用计算函数十次出现两种不同结果的问题,这个问题没有查到代码错在哪,推翻重写,最后遇到的问题是部分字符串可以运算,但还有相当一部分字符串结果不对,后经设置断点查看变量内容的方式,成功的发现了一个if语句中的==号被错打成=,这样的错误非常低级。 2.算法的时间复杂度和空间复杂度分析 本程序的核心算法是求字符串的算式结果部分,由于核心代码部分没有参考任何现有的算法,程序的空间复杂度和时间复杂度都较高,下一步考虑采用逆波兰式的形式对核心代码进行改进。 3.程序存在的不足 “趣味计算”程序虽然能解决小学生在学习四则运算过程中没有实际例题应用的痛点,但还有以下几个缺点 (1)没有采用图形化界面交互不够友好 (2)不能生成可变长度的算式只能生成四个数字计算的算式 (3)没有设定权限系统不支持多用户使用 五、用户手册 1.双击“趣味计算.exe”文件打开主界面如图5.1所示 图5.1主界面运行截图 2.按下键盘上的任意键进入主菜单如图5.2所示 图5.2主菜单运行截图 3.键盘按下1可以更新题库,按Y确定更新,等待进度条跑满题目更新成功如图5.3-5.5所示 图5.3更新题目运行截图 图5.4更新题目运行截图 图5.5更新题目运行截图 4.题目更新成功三秒后自动返回如图5.2所示的主菜单,在主菜单中输入2进入答题。 答题过程中遇到等待时间输入esc键可以停止测试。 程序运行结果如图5.6-5.9所示 图5.6答题界面截图 图5.7答题界面截图 图5.8答题运行截图 图5.9答题运行截图 六、测试结果 本例中仅对核心代码进行测试 字符串算式 Calculation函数返回值 (5-9-4)-2 -10 6/2*(5-7) -6 5/(9+4)/8 0 (8/3+9)*5 58 5-4/(3-5) 7 3*1-(3/5) 2 3-1+7-1 8 七、附录源程序文件名清单 趣味计算.cpp//主程序 data.txt//保存算式的数据文件 history.txt//保存历史分数的文件 趣味计算.exe//可执行程序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 趣味 算式
![提示](https://static.bingdoc.com/images/bang_tan.gif)