软件工程课程作业--四则运算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--;
            软件工程第一次作业

寒假作业2

现代软件工程课程作业 第一章第1题

matlab实现<现代科学运算>课程作业

课程总结和建议

软件工程个人作业03