源代码:

//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;
    }
}

测试用例:

1:验证结果正确性:

测试用例:测试输出30个式子,输出到屏幕上,有乘除法,有括号,有负数,有余数,范围为0-100

测试预期结果:

       出现30个运算式,运算式有出现括号,每种括号出现形式均包括,但不出现无意义的括号

测试结果:

 

2、验证是否所有的边界条件都满足

测试用例:测试当输入表达式数量为0、数值上限小于1时

测试预测结果:要求重新输入表达式数量、数值上限

测试结果:

3、检查能否强制出现错误

测试用例:在选择是否出现乘除法,是否出现括号等问题时,不输入1,2 ,输入其他

测试预测结果:要求重新输入

测试结果:

4、测试有序性

测试用例:测试出现多个运算式,观察运算式中是否有无意义的括号出现

测试预期结果:运算式中每个括号都有意义

测试结果:

5、测试是否满足性能要求:

测试用例:有无乘除有无括号时运算式的状态

测试预期结果:符合题目要求

测试结果:

6、测试输入到文件是否会出现问题

测试用例:选择输出到文件

测试预期结果:problems.txt文件中存入了运算式

测试结果: