一.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 }
五.性能分析