题目要求:
1、避免题目重复
2、可定制(数量/打印方式)
3、可以控制下列参数
(1)是否有乘除法
(2)是否有括号
(3)数值范围
(4)加减有无负数
(5)除法有无余数
关键设计思想:
operationSymbol(int &isMulAndDiv)用于确定运算式是否有乘除法
DivisorNotZore(int &Divisor,int RangeNum)用于保证除数不为0
Remainder(int number1,int &number2,int RangeNum)用于保证没有余数
Neg(int number1,int &number2,int RangeNum)用于避免减法出现负数
若用户选择有括号的运算式,程序通过循环一下步骤依次得到运算式:
1、通过随机数取得运算式中数的个数,执行2。
2、通过循环在0,1之间取随机数判断是否出现左括号,存放在problems[1000][100]相应位置,Rbr记录出现的次数,leftParenthese[100]记录左括号在表达式中的位置,执行3。
3、通过随机数取得数,存入number数组相应位置,在problems[1000][100]相应位置用字符‘n'代替存储,执行4。
4、通过循环在0,1之间取随机数判断是否出现左括号,若出现,则与右括号匹配,同时排除无意义的括号,执行5。
5、在输入最后一个数之前通过随机数0-4选择运算符,将运算符存放在problems[1000][100]相应位置,执行6。
6、执行2,直到输入数的个数符合条件执行7。
7、判断这个运算式是否与前面的运算式重复,若重复,则舍弃这个运算式,重新执行1。
若用户选择没有括号的运算式,程序选择通过循环下列步骤依次得到运算式:
1、通过随机数取得运算式中数的个数,执行2。
2、通过通过随机数取得数,存入number数组相应位置,在problems[1000][100]相应位置用字符‘n'代替存储,执行3。
3、在输入最后一个数之前通过随机数0-4选择运算符,将运算符存放在problems[1000][100]相应位置,执行4
4、执行2,直到输入数的个数符合条件执行5。
5、判断这个运算式是否与前面的运算式重复,若重复,则舍弃这个运算式,重新执行1。
若用户选择在屏幕上显示运算式,则依次将存放在problems的字符显示出来,遇到字符’n',则输出对应数字
若用户选择在problems.txt文件中保存运算式,则依次将存放在problems的字符输入到文件中,遇到字符’n',则输入对应数字
源程序代码:
//2016 3.6 Cheng Qiqin //四则运算改进 #include <iostream> #include<ctime> #include<cstdlib> #include<iomanip> #include<fstream> using namespace std; void proNum(int &ProNum)//确定题目数量 { cout<<"请输入运算式的数量: "; cin>>ProNum; if(ProNum<1) { cout<<"输入错误,"; proNum(ProNum); } } void typeway(int &type)//确定打印方式 { cout<<"请输入打印方式(1、输出到屏幕 2、输出到文件): "; cin>>type; if(type>2||type<1) { cout<<"输入错误,"; typeway(type); } } void ismulAndDiv(int &isMulAndDiv)//确定是否有乘除法 { cout<<"是否有乘除法(1、是 2、否):"; cin>>isMulAndDiv; if(isMulAndDiv<1||isMulAndDiv>2) { cout<<"输入错误,"; ismulAndDiv(isMulAndDiv); } } int operationSymbol(int &isMulAndDiv)//确定是否有乘除法 { if(isMulAndDiv==1) { return 4; } else { return 2; } } void isparenthese(int &isParenthese)//确定是否有括号 { cout<<"是否有括号(1、是 2、否): "; cin>>isParenthese; if(isParenthese<1||isParenthese>2) { cout<<"输入错误,"; isparenthese(isParenthese); } } void isneg(int &isNeg)//确定加减有无负数 { cout<<"加减有无负数(1、有 2、无): "; cin>>isNeg; if(isNeg<1||isNeg>2) { cout<<"输入错误,"; isneg(isNeg); } } void isremainder(int &isRemainder)//确定除法有无余数 { cout<<"除法有无余数(1、有 2、无): "; cin>>isRemainder; if(isRemainder<1||isRemainder>2) { cout<<"输入错误,"; isremainder(isRemainder); } } void DivisorNotZore(int &Divisor,int RangeNum)//排除除数为0 { while(Divisor==0) { Divisor=rand()%RangeNum; } } void Neg(int number1,int &number2,int RangeNum)//排除形如a-b结果为负的情况 { while(number1<number2) { number2=rand()%RangeNum; } } void Remainder(int number1,int &number2,int RangeNum)//排除有余数的情况 { while((number1%number2)!=0) { number2=rand()%RangeNum; DivisorNotZore(number2,RangeNum); } } void main() { srand((int)time(0)); //设定时间种子 int ProNum,type,isMulAndDiv,isParenthese,RangeNum,isNeg,isRemainder; int number[100][10],Prolength[100],Rbr=0,num,i,j,n; //number[100][10]用于存放每个表达式中数字,Prolength[100]用于记录表达式的长度 char Problems[100][100];// Problems[100][100]用于存放表达式 char fuhao[4]={'+','-','*','/'}; proNum(ProNum); typeway(type); ismulAndDiv(isMulAndDiv); isparenthese(isParenthese); isneg(isNeg); if(isMulAndDiv==1) { isremainder(isRemainder); } cout<<"请输入数值范围:"<<endl; cout<<"请输入上限:"; cin>>RangeNum; if(RangeNum<1){ cout<<"输入错误,请重新输入上限:"; cin>>RangeNum; } if(isParenthese==1)//有括号 { for(i=0;i<ProNum;i++) { num=rand()%8+2;//随机得出每个表达式中数的个数 j=0; int leftParenthese[100],loc=0; if(num==2)//运算式中只有两个数时,不需要括号 { for(n=0;n<num;n++) { Problems[i][j]='n'; number[i][n]=rand()%RangeNum; if(Problems[i][j-1]=='/')//排除除号后面的数为0的情况 { DivisorNotZore(number[i][n],RangeNum); } j++; if(n<num-1)//添加运算符 { Problems[i][j]=fuhao[rand()%operationSymbol(isMulAndDiv)]; j++; } } Prolength[i]=j;//记录运算式的长度 } else//运算式中数超过两个,出现括号 { for(n=0;n<num;n++) { while(rand()%2)//添加左括号 { Rbr++; Problems[i][j]='('; leftParenthese[loc]=j; loc++; j++; } Problems[i][j]='n'; number[i][n]=rand()%RangeNum;//排除除号后面的数为0的情况 if(Problems[i][j-1]=='/') { DivisorNotZore(number[i][n],RangeNum); } j++; while(rand()%2==0)//添加右括号 { if(Rbr>0) { Rbr--; loc--; if(Problems[i][j-2]=='(')//排除形如(20)的情况 { Problems[i][j-2]=Problems[i][j-1]; j--; } else { if(Problems[i][leftParenthese[loc]]=='('&&Problems[i][leftParenthese[loc]+1]=='('&&Problems[i][j-1]==')') { for(int loction=leftParenthese[loc];loction<j-1;loction++) { Problems[i][loction]=Problems[i][loction+1]; } j--; } else { Problems[i][j]=')'; j++; } } } else{ break; } } if(n<num-1)//添加运算符 { Problems[i][j]=fuhao[rand()%operationSymbol(isMulAndDiv)]; j++; } } while(Rbr>0)//保证左括号数量与右括号数量相等 { Rbr--; loc--; if(Problems[i][j-2]=='(')//排除形如(20)的情况 { Problems[i][j-2]=Problems[i][j-1]; j--; } else { if(Problems[i][leftParenthese[loc]]=='('&&Problems[i][leftParenthese[loc]+1]=='('&&Problems[i][j-1]==')') { for(int loction=leftParenthese[loc];loction<j-1;loction++) { Problems[i][loction]=Problems[i][loction+1]; } j--; } else { Problems[i][j]=')'; j++; } } } Prolength[i]=j; } for(int k=0;k<i;k++)//排除运算式重复 { if(Problems[k]==Problems[i]) { i--; break; } } } } else { for(i=0;i<ProNum;i++){ num=rand()%8+2; j=0; for(n=0;n<num;n++){ Problems[i][j]='n'; number[i][n]=rand()%RangeNum; if(Problems[i][j-1]=='/')//排除除号后面的数为0的情况 { DivisorNotZore(number[i][n],RangeNum); } j++; if(n<num-1)//添加运算符 { Problems[i][j]=fuhao[rand()%operationSymbol(isMulAndDiv)]; j++; } } Prolength[i]=j;//记录运算式的长度 for(int k=0;k<i;k++)//排除重复 { if(Problems[k]==Problems[i]) { i--; break; } } } } int s,t,q; ofstream of("problems.txt"); if(!of) exit(1); for(i=0;i<ProNum;i++)//表达式数量 { s=0; t=0; q=Prolength[i]; while(Problems[i][s]=='('&&Problems[i][q-1]==')')//排除表达式首尾都有括号且无意义时的情况 { int m,n=0; bool kuohao=true; for(m=s;m<q-1;m++) { if(Problems[i][m]=='(') { n++; } if(Problems[i][m]==')') { n--; } if(n==0) { kuohao=false; break; } } if(kuohao) { s++; Prolength[i]=Prolength[i]-2; q=q-1; } else { break; } } while(Prolength[i]>0) { if(Problems[i][s]=='n') { if(t>0) { if(isNeg==2) { if(Problems[i][s-1]=='-'&&Problems[i][s-2]=='n') { Neg(number[i][t-1],number[i][t],RangeNum); } } if(isRemainder==2) { if(Problems[i][s-1]=='/'&&Problems[i][s-2]=='n') { Remainder(number[i][t-1],number[i][t],RangeNum); } } } if(type==1) { cout<<number[i][t]; } else { of<<number[i][t]; } s++; t++; } else { if(type==1) { cout<<Problems[i][s]; } else { of<<Problems[i][s]; } s++; } Prolength[i]--; } if(type==1) { cout<<"="<<endl; } else { of<<"="<<endl; } } of.close(); if(type==1) { cout<<"出题完毕!"<<endl; } else { cout<<"出题完毕,题目已成功存入problems.txt!"<<endl; } }
运行结果截图:
项目计划日志:(单位:min)
时间记录日志:
缺陷记录日志:
程序已实现功能:
避免题目重复
可定制(数量/打印方式)
可以控制下列参数
(1)是否有乘除法
(2)是否有括号
(3)数值范围
程序部分实现功能:
(4)加减有无负数
(5)除法有无余数
未实现部分:
未能实现运算式的计算
未实现原因:
不能预测括号中计算后出现的结果
实现部分:
仅能保证两个数之间没有括号的减法不出现负数,除法不出现余数