一.github地址
https://github.com/Zhaoziqingg/size
二.各模板开发时间
PSP2.1 | Personal Software Process Stages | 预估耗时 (分钟) | 实际耗时 (分钟) |
Planning | 计划 | 90 | 60 |
·Estimate | ·估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 1000 | 1200 |
·Analysis | ·需求分析(包括学习新技术) | 100 | 100 |
·Design Spec | ·生成设计文档 | 240 | 200 |
·Design Review | ·设计复审 | 50 | 60 |
·Coding Standard | ·代码规范 | 25 | 25 |
·Design | ·具体设计 | 200 | 280 |
·Coding | ·具体编码 | 1200 | 1300 |
·Code Review | ·代码复审 | 60 | 45 |
·Test | ·测试 | 40 | 60 |
Reporting | 报告 | 90 | 120 |
·Test Report | ·测试报告 | 30 | 15 |
·Size Measurement | ·计算工作量 | 15 | 15 |
·Postmortem&Process Improvement Plan | ·事后总结并提出过程改进计划 | 60 | 80
|
| 合计 | 3210 | 3300 |
三.设计思路
1.四则运算是最基础的运算, 除去结果的判断,还要实现题目的生成,所以将整个项目划分成若干个子函数,分别考虑其实现过程。
(1).生成随机操作数和随机运算符,采用堆栈存储,便于计算,并组合成随机表达式。
(2).将产生的表达式求解,并与用户输入的结果进行对照,记录其正确率。
(3).设计合理的输入格式以及提示,可以让用户自行设计表达式的难易程度。
(包括但不限于表达式的个数,操作数的个数,位数,运算符的个数,允许出现的操作数类型)。
2.实现文件输入输出。
3.上传github。
四.设计实现过程
1.主要函数
double Operate(double a,char theta,double b); int createOperateNum(int bit); //产生随机数rand() 生成的是0~32767之间,不大于bit位的一个随机数。 char createOperateChar(int i);//随机生成运算符 void getInputData(); //输入习题数,操作数位数,操作数个数,操作数规范,运算符种类等。 void createOperate();//生成表达式,根据当前时间生成随机数生成器种子,并按照用户输入的规定进行拼装。 double EvaluateExpression(double &p); //表达式求解 void Savefile(); int Loadfile();
2.生成运算符
1 char createOperateChar(int i) 2 { 3 int randomNumber,randomdata; 4 randomNumber = rand(); 5 randomdata = (randomNumber % i); 6 7 return operateChar[randomdata]; 8 }
3.用户输入
void getInputData() { cout<<"请输入习题数(习题数规定至少不小于5):"<<endl; cin>>in.no; while(in.no<5) //如果输入题数in.no小于5,则请重新输入 { cout<<"您的输入题数不够,请重新输入"<<endl; cin>>in.no; } cout<<"请输入操作数个数:"<<endl; cin>>in.operateNo; cout<<"请输入操作数位数"<<endl; cin>>in.operateBit; cout<<"运算中间结果是否允许为小数,1代表能,0代表不能"<<endl; cin>>in.isFraction; if(in.isFraction==1) { cout<<"请输入您想保留的小数位数m(m≥0且m≤4):"<<endl; cin>>m; } cout<<"运算中间结果是否允许为负数,1代表能,0代表不能"<<endl; cin>>in.isNegative; cout<<"请输入结果允许出现的最大值:"<<endl; cin>>in.scopemax; cout<<"请输入结果允许出现的最小值:"<<endl; cin>>in.scopemin; cout<<"请输入您想要使用的操作符,并以'#'结束输入:"<<endl; char c[6]; opType=0; int i=0; cin>>c; while(c[i]!='#') { if(c[i]=='+'||c[i]=='-'||c[i]=='*'||c[i]=='/') if(opType<4)operateChar[opType++]=c[i]; i++; } }
4.生成运算式
1 void createOperate() 2 { 3 int i=in.operateNo; 4 srand((unsigned)time(NULL));//根据当前时间生成随机数生成器种子 5 while(i>0) 6 { 7 stackNum[stackNumNo++]=createOperateNum(in.operateBit); 8 stackOpChar[stackOpCharNo++]=createOperateChar(opType); 9 i--; 10 } 11 stackNumNo--; 12 stackOpCharNo--;//将多产生的一个操作符删除; 13 stackOpChar[stackOpCharNo]='#'; 14 stackOpCharNo--; 15 }
5.计算表达式
1 double EvaluateExpression(double &p) 2 { 3 SqStack OPTR; SqStack1 OPND; 4 int i=1,j=1; char c; 5 double q; 6 InitStack(OPTR); InitStack(OPND); 7 Push(OPND,stackNum[0]); Push(OPTR,stackOpChar[0]); Push(OPND,stackNum[1]); 8 while(i<stackNumNo) 9 { 10 if(stackOpChar[i]!='#') 11 switch(Precede(GetTop(OPTR),stackOpChar[i])) 12 { 13 case '<': 14 Pop(OPND,p); 15 p=Operate(p,stackOpChar[i],stackNum[j+1]); 16 if((in.isNegative==0&&p<0)||(in.isFraction==0&&p!=int(p)))error=true; 17 Push(OPND,p); 18 break; 19 case '>': 20 Pop(OPTR,c); 21 Pop(OPND,p); Pop(OPND,q); 22 p=Operate(q,c,p); 23 if((in.isNegative==0&&p<0)||(in.isFraction==0&&p!=int(p)))error=true; 24 Push(OPND,p); 25 Push(OPND,stackNum[j+1]); 26 Push(OPTR,stackOpChar[i]); 27 break; 28 } 29 i++; 30 j++; 31 } 32 Pop(OPTR,c); 33 Pop(OPND,p); Pop(OPND,q); 34 p=Operate(q,c,p); 35 if(p<in.scopemin||p>in.scopemax||(in.isNegative==0&&p<0)||(in.isFraction==0&&p!=int(p))) //当p被指定为不能为负数时,p<0 36 error=true; //p不能小于指定的最小值,不能大于指定的最大值 37 return 0; 38 }
6.文件保存
1 void Savefile() 2 { 3 ofstream outfile("1.txt"); 4 if(!outfile) 5 { 6 cout<<"Open 1.txt error!"<<endl; 7 return; 8 } 9 outfile<<in.isFraction<<" "<<in.isNegative<<" "<<in.no<<" "<<in.operateBit<<" "<< 10 in.operateNo<<" "<<in.scopemax<<" "<<in.scopemin<<" "<<opType<<" "; 11 for(int i=0;i<opType;i++)outfile<<operateChar[i]; 12 } 13 int Loadfile() 14 { 15 ifstream infile("1.txt"); 16 if(!infile) 17 { 18 cout<<"Open 1.txt error!"<<endl; 19 return 0; 20 } 21 infile>>in.isFraction>>in.isNegative>>in.no>>in.operateBit>>in.operateNo>>in.scopemax>>in.scopemin>>opType; 22 for(int i=0;i<opType;i++)infile>>operateChar[i]; 23 return 1; 24 }
7.主函数
1 int main() 2 { 3 // Loadfile(); 4 //用户输入数据 5 double p,result; 6 char t; 7 int correct=0,fail=0,j=Loadfile(); 8 if(!j)getInputData(); 9 else 10 { 11 cout<<"是否需要重新输入数据(y/n)"<<endl; 12 cin>>t; 13 if(t=='y')getInputData(); 14 } 15 16 Savefile(); 17 cout<<in.no<<endl; 18 19 20 //产生相应的运算式 21 while(in.no>0) 22 { 23 createOperate(); 24 EvaluateExpression(p); 25 if(!error) 26 { 27 int i=0; 28 while(i<=stackOpCharNo) 29 { 30 cout<<stackNum[i]<<stackOpChar[i]; 31 i++; 32 } 33 cout<<stackNum[i]<<"="<<endl; 34 /// 35 cout<<"请输入您的运算结果:"<<endl; 36 cin>>result; 37 if(in.isFraction==1) 38 { 39 if((int)(p*pow(10,m+1))%10>=5) 40 p=(int)(p*pow(10,m)+1)/pow(10,m); 41 else p=(int)(p*pow(10,m))/pow(10,m); 42 } 43 44 if(p==result) 45 { 46 cout<<"正确"<<endl; 47 correct++; 48 } 49 else 50 { 51 cout<<"错误"<<endl; 52 cout<<"正确答案应为:"<<p<<endl; 53 fail++; 54 } 55 in.no--; 56 } 57 reset(); 58 } 59 cout<<"您一共做对了"<<correct<<"题,做错了"<<fail<<"题"<<endl; 60 return 0; 61 }
五.性能分析