zoukankan      html  css  js  c++  java
  • 软件工程课程作业(二)--四则运算2改进版(c++)

    题目要求:

    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)除法有无余数

     未实现部分:

    未能实现运算式的计算

    未实现原因:

    不能预测括号中计算后出现的结果

    实现部分:

    仅能保证两个数之间没有括号的减法不出现负数,除法不出现余数

  • 相关阅读:
    Android 7.0 UICC 分析(二)
    Android 7.0 UICC 分析(一)
    痛风有治吗?
    <学习笔记> 数论
    <学习笔记> 高精度 +
    <学习笔记> 线段树
    <学习笔记?> 链表
    <学习笔记> 手打堆模板
    <学习笔记> 倍增 lca
    <学习笔记> 最小生成树 Kruskal
  • 原文地址:https://www.cnblogs.com/chengqiqin07/p/5268600.html
Copyright © 2011-2022 走看看