四则运算3
Posted GloryYT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算3相关的知识,希望对你有一定的参考价值。
本次作业的题目:
在四则运算2的基础上,再添加一些条件,总共要求满足如下条件:
1.题目避免重复。
2.可制定。(数量/打印方式)
3.可以控制下列参数:
- 是否有乘除法
- 是否有括号(最多可支持10个数参与计算)
- 数值范围
- 加减有无负数
- 乘除有无余数
(新要求)
4.学生写的程序必须能判定用户的输入答案是否正确
5.程序必须能处理混合四则运算
PS:连续的减法和除法,应该遵循做结合的规定;连续除法要打括号。
设计思想:
1.因为这次是结对开发,两个人结对,并且再上一次的程序基础上进行拓展,所以比较了一下各自的程序,选出较优秀的那一个。
2.由于要完成的功能非常多,可以划分多个模块实现,便于多个功能组合。
3.第一个模块就是出现连除的情况,我们程序是随机出现括号的,如果出现连除的情况,必须在后方添加括号。
4.括号的实现,利用整型转化成字符串型来进行解决,括号随机出现左边或者右边,保存在数组之内。
5.实现真分数以及真分数的运算,运算方式直接利用分数的加减乘除运算规则来实现。
6.结果的验证,将四则运算算式转化成字符串,利用压栈入栈的数据结构计算四则运算表达式,正确的结果与输出入的结果进行比较,得出答案是否正确。
代码:
//随机生成四则运算表达式 杨超群 杨涛 2016.3.12 #include<iostream> #include<string> #include<time.h> #include <stdio.h> #include<fstream> #include<cmath> #include<sstream> #include<strstream> #include<math.h> #include<iomanip> #define MAX 100 #define False 0 #define True 1 using namespace std; typedef string SelemType; using namespace std; string str1[4]={"+","-","*","/"}; //运算符数组,存储+ - * / int n,m; int num[6]; //随机生成的操作数 char str2[25]; //整数转化为的字符数组 char str3[25]; //整数转化为的字符数组 string str4[100]; int OperatorNum[1000]; //运算符数组,每生成一个运算符存进数组 typedef struct{ SelemType *base; SelemType *top; int stacksize; }Sqstack; void InitStack(Sqstack &s) //栈的初始化 { s.base=new SelemType[MAX]; if(!s.base)exit(1); s.top=s.base; s.stacksize =MAX; } void Push(Sqstack &s,SelemType e) //压入 { if(s.top-s.base==s.stacksize) exit(1); *s.top++=e; } void Pop(Sqstack &s,SelemType &e) //弹出 { if(s.top==s.base) exit(1); e=*--s.top; } SelemType GetTop(Sqstack &s) //取顶 { if(s.top==s.base) exit(1); return *(s.top-1); } int In(SelemType ch) //判断是否为运算符 { if(ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="("||ch==")"||ch=="#") return True; else return False; } SelemType Operate(SelemType a1,SelemType theta,SelemType b1) //计算 { stringstream ss; SelemType c1; double m1,m2; double m3,m4; m1=atof(a1.c_str()); m2=atof(b1.c_str()); if(theta=="+") m3=m1+m2; else if(theta=="-") m3=m1-m2; else if(theta=="*") m3=m1*m2; else if(theta=="/") m3=m1/m2; m4=double((int)(m3*100))/100.0; ss<<m4; ss>>c1; return c1; } char Precede(string theta1,string theta2) //运算符的计算顺序判断 { char chx; if(theta1=="+") { if(theta2=="*"||theta2=="/"||theta2=="(") chx = \'<\'; else chx = \'>\'; } else if(theta1=="-") { if(theta2=="*"||theta2=="/"||theta2=="(") chx = \'<\'; else chx = \'>\'; } else if(theta1=="*") { if(theta2=="(") chx = \'<\'; else chx = \'>\'; } else if(theta1=="/") { if(theta2=="(") chx = \'<\'; else chx = \'>\'; } else if(theta1=="(") { if(theta2==")") chx = \'=\'; else if(theta2=="#") chx=\'$\'; else chx = \'<\'; } else if(theta1==")") { if(theta2=="(") chx = \'$\'; else chx = \'>\'; } else if(theta1=="#") { if(theta2=="#") chx = \'=\'; else if(theta2==")") chx=\'$\'; else chx = \'<\'; } return chx; } string TiQuString(string str,int &i) { string ch; char *q; string p; p=str; q=&p[i]; ch=ch+*q; if((*q>=\'0\')&&(*q<=\'9\')) { i++; int j=1; while((*(q+j)>=\'0\')&&(*(q+j)<=\'9\')) { ch=ch+*(q+j); j++; } i=i+j-1; } else { ch=*q; i++; } return ch; } string OPeration(string str) { string str1; str1=str+"#"; int i=0; string ch; ch=TiQuString(str1,i); SelemType theta,x1,a1,b1; Sqstack OPND,OPTR; InitStack(OPTR); InitStack(OPND); Push(OPTR,"#"); while(ch!="#"||GetTop(OPTR)!="#") { int f; f=In(ch); if(f!=True) { Push(OPND,ch); ch=TiQuString(str1,i); } else { switch(Precede(GetTop(OPTR),ch)) { case \'<\': { Push(OPTR,ch); ch=TiQuString(str1,i); break; } case \'>\': { Pop(OPTR,theta); Pop(OPND,b1);Pop(OPND,a1); Push(OPND,Operate(a1,theta,b1)); break; } case \'=\': { Pop(OPTR,x1); ch=TiQuString(str1,i); break; } case \'$\': { cout<<"该表达式有错"; break; } default:break; } } } return GetTop(OPND); } void Input(int n,int p,int min,int max,int &j,int &q) { int num1,num2,num3,num4,num5; //随机数 int c=0; //指向第一个运算符数组的下标 int s=0; //括号的个数 string str; ofstream outfile; outfile.open("a.txt",ios::app); if(!outfile) { cerr<<"OPEN ERROR!"<<endl; exit(0); } num1=rand()%(max-min+1)+min; num2=rand()%(max-min+1)+min; num3=rand()%4; //随机数指向运算符数组的下标 itoa(num1,str2,10); //整数转化为字符数组 itoa(num2,str3,10); //整数转化为字符数组 str=str2+str1[num3]+str3; //生成表达式 OperatorNum[c]=num3; //当前生成的符号存入OperatorNum数组里 c++; n=n-2; //消耗了两个操作数 while(n!=0) //当n不等于0时,循环生成str,即表达式+符号+表达式的形式 { num4=rand()%2; if(num4==0) //上一个str放在符号的左边 { num5=rand()%2; if(s<=3) { if(num5==0) //上一个str不加括号 { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) //避免生成6/3/2的形式 str="("+str+")"+str1[num3]+str2; else str=str+str1[num3]+str2; } else //上一个str加括号 { num3=rand()%4; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); str="("+str+")"+str1[num3]+str2; s++; } } else { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) //避免生成6/3/2的形式 str="("+str+")"+str1[num3]+str2; else str=str+str1[num3]+str2; } } else //上一个str放在符号的右边 { num5=rand()%2; if(s<=3) { if(num5==0) // 上一个str不加括 { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) str=str2+str1[num3]+"("+str+")"; else str=str2+str1[num3]+str; } else //上一个str加括号 { num3=rand()%4; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); str=str2+str1[num3]+"("+str+")"; s++; } } else { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) str=str2+str1[num3]+"("+str+")"; else str=str2+str1[num3]+str; } } n--; //消耗一个操作数 } string result1,result2; //result1表示用户输入的答案,result2表示程序计算的结果 str4[p]=str; //把str存入字符串数组str4中 for(int i=0;i<p;i++) //查询四则运算式是否有重复 if(str4[i]==str4[p]) Input(m,p,min,max,j,q); cout<<str4[p]<<"="; result2=OPeration(str); //计算四则表达式 cin>>result1; if(result1==result2) //判断结果是否正确 { cout<<"计算正确"; j++; } else { cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2; q++; } outfile<<str4[p]<<endl; cout<<endl; } void Input1(int n,int p,int min,int max,int &j,int &q) { int num1,num2,num3,num4; int c=0; int s=0; string str; ofstream outfile; outfile.open("a.txt",ios::app); if(!outfile) { cerr<<"OPEN ERROR!"<<endl; exit(0); } num1=rand()%(max-min+1)+min; num2=rand()%(max-min+1)+min; num3=rand()%4; itoa(num1,str2,10); itoa(num2,str3,10); str=str2+str1[num3]+str3; OperatorNum[c]=num3; c++; n=n-2; while(n!=0) //当n不等于0时,循环生成str,即表达式+符号+表达式的形式 { num4=rand()%2; if(num4==0) //上一个str放在符号的左边 { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) //避免生成6/3/2的形式 str="("+str+")"+str1[num3]+str2; else str=str+str1[num3]+str2; } else //上一个str放在符号的右边 { num3=rand()%4; OperatorNum[c]=num3; c++; num1=rand()%(max-min+1)+min; itoa(num1,str2,10); if((num3==3)&&(OperatorNum[c-2]==3)) str=str2+str1[num3]+"("+str+")"; else str=str2+str1[num3]+str; } n--; } string result1,result2; str4[p]=str; //把str存入字符串数组str4中 for(int i=0;i<p;i++) //查询四则运算式是否有重复 if(str4[i]==str4[p]) Input(m,p,min,max,j,q); cout<<str4[p]<<"="; result2=OPeration(str); cin>>result1; if(result1==result2) { cout<<"计算正确"; j++; } else { cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2; q++; } outfile<<str4[p]<<endl; cout<<endl; } void sort(int min,int max){ //生成四个随机数并排序 num[0]=rand()%(max-min+1)+min; num[1]=rand()%(max-min+1)+min; num[2]=rand()%(max-min+1)+min; num[3]=rand()%(max-min+1)+min; for(int i=0;i<4;i++){ for(int j=0;j<i;j++){ if(num[i]>num[j]) { int temp=0; temp=num[i]; num[i]=num[j]; num[j]=temp; } } } } void sort1(int min,int max) //生成两个随机数,并排序 { num[4]=rand()%(max-min+1)+min; num[5]=rand()%(max-min+1)+min; for(int i=4;i<6;i++){ for(int j=4;j<i;j++){ if(num[i]>num[j]) { int temp=0; temp=num[i]; num[i]=num[j]; num[j]=temp; } } } } void Simplification(int &m,int &n) //真分数化简 { int x,y,i,p; //公约数p if(m>=n) { x=n; y=m; } if(m<n) { x=m; y=n; } for(i=x;i>0;i--) { if(x%i==0&&y%i==0) { p=i; break; } } m=m/p; n=n/p; } void Input2(int n,int p,int min,int max,int &j,int &q) { int num3,num4,s=0; string str,strr2,strr3,str5,str6,str7,str8,str9; stringstream ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8; ofstream outfile; outfile.open("a.txt",ios::app); if(!outfile) { cerr<<"OPEN ERROR!"<<endl; exit(0); } num3=rand()%4; sort(min,max); Simplification(num[0],num[3]); Simplification(num[1],num[2]); ss1<<num[0]; ss1>>strr2; ss2<<num[1]; ss2>>strr3; ss3<<num[2]; ss3>>str5; ss4<<num[3]; ss4>>str6; if((str5!=strr3)&&(str6!=strr2)) //避免生成分子分母相等的表达式 str="("+str5+"/"+strr3+")"+str1[num3]+"(Python 3学习笔记获取 badarith,[erlang,'+',[error,0],[],同时使用 Erlang 片段在 TSUNG 中执行算术运算