软件工程课程作业--四则运算3(C++)
Posted 糖兜兜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程课程作业--四则运算3(C++)相关的知识,希望对你有一定的参考价值。
伙伴链接:http://www.cnblogs.com/haoying1994/
一、设计思路
在此前程序拥有的功能:加减有无负数,除法有无余数以及算式可定制的功能的基础上,此次程序又添加了算式结果的计算,提示用户结果正确与否,正确与错误个数和用户意志存入数组的功能。
1.对于运算符的选择和算式个数,各算式的长短均利用随机数函数产生。
2.对于算式计算方面:
只有两个数的加减乘除没有括号时:在减时考虑是否出现负数,除时考虑是否出现余数。
多个数的加减没有乘除和括号时:遇到减号考虑前面结果是否小于减数,是则改变运算符为加号以确保最终结果没有负数。
多个数的加减乘除没有括号时:在检索到式子中的乘除号时,判断其后面的符号,若有连续的乘除号,特别是有除号的时候,考虑是否需要余数,若有余数则利用找被除数因子的方法使连除的时候得数为整数,若无余数则将被除数和除数分别作为分子和分母保存起来。之后将只含有乘除号的连续子式先算出存入另一数组中,再与加减号相连的数进行相应的运算,在遇到加减运算符时,如果有余数,则利用通分的方法将结果保存为分数的形式。之后判断是否需要有负数,如果不需要负数,则在遇到减号时,将处在减数位置的式子利用随机数进行数值的重组,直到被减数大于减数为止。
3.对于算式输出方面:文件输出使用了ofstream文件输出流,输出到problems.txt中。 4.对于用户输入答案,判断用户输入字符串是否与正确结果相匹配,如果匹配,则提示恭喜你,答对了,否则提示回答错误,并且给出正确答案。利用循环计数判断正确回答题目的个数,在答题结束后显示在屏幕上。
不能实现的部分是当有括号有乘除的部分,有思路,写了代码,但是有bug,尚未实现,在源程序中注释掉的部分。
二、源程序代码
//2016 3.14 Cheng Qiqin HaoYing //四则运算 #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 upperLimit(int &RangeNum)//确定数值的范围 { cout<<"请输入数值范围:"<<endl; cout<<"请输入上限:"; cin>>RangeNum; while(RangeNum<1){ cout<<"输入错误,请重新输入!"<<endl; upperLimit(RangeNum); } } 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 properFraction(int &number1,int &number2)//将分数化简 { int m=0; if(number1<0) { number1=0-number1; while(m<=number1) { for(m=2;m<=number1;m++)//寻找分子分母公约数,并且约分 { if(number1%m==0&&number2%m==0) { number1=number1/m; number2=number2/m; m=2; break; } } } number1=0-number1; } else { while(m<=number1) { for(m=2;m<=number1;m++) { if(number1%m==0&&number2%m==0) { number1=number1/m; number2=number2/m; m=2; break; } } } } } int main() { srand((int)time(0)); //设定时间种子 int userChoose[6]; //保存用户意志 int ProNum/*,type*/,isMulAndDiv,isParenthese,RangeNum,isNeg,isRemainder; int number[1000][10],Prolength[100],Rbr=0,num,i,j,n; //number[1000][10]用于存放每个表达式中数字,Prolength[100]用于记录表达式的长度 char Problems[1000][100];// Problems[1000][100]用于存放表达式 char fuhao[4]={\'+\',\'-\',\'*\',\'/\'};//用于存放操作符号 int result[1000][2],resultNum[2]; char input[100]; int isInput[2]; int NumOfRightPro=0; proNum(ProNum); userChoose[0]=ProNum; //typeway(type); ismulAndDiv(isMulAndDiv); userChoose[1]=isMulAndDiv; isparenthese(isParenthese); userChoose[2]=isParenthese; isneg(isNeg); userChoose[3]=isNeg; if(isMulAndDiv==1)//选择了有乘除法才需要考虑是否有余数的问题 { isremainder(isRemainder); } upperLimit(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++; } } result[i][0]=number[i][0]; result[i][1]=1; switch(Problems[i][j-2])//将两数运算结果存放到result[i][0]中 { case \'+\': result[i][0]=result[i][0]+number[i][1]; break; case \'-\': if(isNeg==2)//如果选择没有负数 { Neg(number[i][0],number[i][1],RangeNum); } result[i][0]=result[i][0]-number[i][1]; break; case \'*\': result[i][0]=result[i][0]*number[i][1]; break; case \'/\': if(isRemainder==2)//如果选择没有余数 { Remainder(number[i][0],number[i][1],RangeNum); result[i][0]=result[i][0]/number[i][1]; } else//如果选择有余数 { if(number[i][0]%number[i][1]==0)//两数相除可以除尽 { result[i][0]=number[i][0]/number[i][1]; } else//两数相除结果为分数 { result[i][1]=number[i][1]; properFraction(result[i][0],result[i][1]); } } break; default: break; } 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; if(Problems[i][j-1]==\'/\')//排除除号后面的数为0的情况 { 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)]; if(j>4)//根据小学六年级数学,排除连续三个以上乘号和除号出现 { if(Problems[i][j]==\'/\'&&Problems[i][j-2]==\'/\'&&Problems[i][j-4]==\'/\') { Problems[i][j]=fuhao[rand()%3]; } if(Problems[i][j]==\'*\'&&Problems[i][j-2]==\'*\'&&Problems[i][j-4]==\'*\') { Problems[i][j]=\'+\'; } } 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; int operand[10][2],op=0,t=0; int k=0,m=0; int getNeg=0; char operation[100]; if(isMulAndDiv==2) { while(k<j) { operation[m]=Problems[i][k]; if(operation[m]==\'(\') { m++; } else if(operation[m]==\'n\') { operand[op][0]=number[i][t]; op++; if(op>1) { if(operation[m-2]==\'n\') { switch(operation[m-1]) { case \'+\': operand[op-2][0]=operand[op-2][0]+operand[op-1][0]; break; case \'-\': if(isNeg==2) { Neg(operand[op-2][0],number[i][t],RangeNum); operand[op-1][0]=number[i][t]; } operand[op-2][0]=operand[op-2][0]-operand[op-1][0]; break; default: break; } m=m-1; op--; t++; } else { m++; t++; } } else { m++; t++; } } else if(operation[m]==\')\') { operation[m-2]=operation[m-1]; m=m-1; if(op>1) { if(operation[m-3]==\'n\') { switch(operation[m-2]) { case \'+\': operand[op-2][0]=operand[op-2][0]+operand[op-1][0]; break; case \'-\': operand[op-2][0]=operand[op-2][0]-operand[op-1][0]; if(isNeg==2) { if(operand[op-2][0]<0) { getNeg=1; break; } } break; default: break; } m=m-2; op--; } } } else { m++; } k++; } } //下面注释掉的内容为括号中有乘除的计算过程 // else // { // while(k<j) // { // operation[m]=Problems[i][k]; // if(operation[m]==\'(\') // { // m++; // } // else if(operation[m]==\'n\') // { // operand[op][0]=number[i][t]; // operand[op][0]=1; // op++; // if(op>1) // { // if(operation[m-2]==\'n\') // { // switch(operation[m-1]) // { // case \'+\': // if(op>2) // { // if(operation[m-4]==\'n\') // { // switch(operation[m-3]) // { // case \'+\': // operand[op-3][0]=operand[op-3][0]*operand[op-2][1]+operand[op-2][0]*operand[op-3][1]; // operand[op-3][1]=operand[op-3][1]*operand[op-2][1]; // operand[op-2][0]=operand[op-1][0]; // operand[op-2][1]=operand[op-1][1]; // operation[m-3]=operation[m-1]; // operation[m-2]=operation[m]; // break; // case \'-\': // operand[op-3][0]=operand[op-3][0]*operand[op-2][1]+operand[op-2][0]*operand[op-3][1]; // operand[op-3][1]=operand[op-3][1]*operand[op-2][1]; // operand[op-2][0]=operand[op-1][0]; // operand[op-2][1]=operand[op-1][1]; // operation[m-3]=operation[m-1]; // operation[m-2]=operation[m]; // break; // case \'*\': // operand[op-2][0]=operand[op-2][0]*operand[op-1][0]; // operand[op-2][1]=operand[op-2][1]*operand[op-1][1]; // operation[m-2]=operation[m]; // break; // case \'/\': // operand[op-2][0]=operand[op-2][0]*operand[op-1][1]; // operand[op-2][1]=operand[op-2][1]*operand[op-1][0]; // operation[m-2]=operation[m]; // break; // default: // break; // } // m--; 软件工程第一次作业