软件工程作业02

四则运算2:

1、题目避免重复;
2、可定制(数量/打印方式);
3、可以控制下列参数:  是否有乘除法; 是否有括号(最多可以支持十个数参与计算);数值范围;加减有无负数;除法有无余数。

一,设计思想

把一些参数设置成全局变量,方便各个函数使用,避免实参虚参搞丢了参数。在主函数里获取了参数之后将主要功能模块另写在一些函数里。利用时间种子生成随机数,随机数的范围利用全局参数控制,利用string数组来储存生成的每一道题目,生成题目的最后一步应该有一个检验过程,就是遍历之前的字符串数组,如果有一样的就不储存,继续生成。最后输出字符串。

二,程序代码

#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
using namespace std;
//全局参数变量设置
int QstNum,IfIncMD,IfIncBrackets,range,IfNeg,IfRem,IfFraction;
//题目数量 是否有乘除 是否有括号 数值范围 是否能有负数 是否能有余数 是否有分数
string a[1000];//用于储存题目
void ParaSet()//参数设置
{
    cout<<"请输入生成的四则运算题个数(1-1000):";
    cin>>QstNum;
    while(QstNum<0&&QstNum>1000)
    {
        cout<<"请重新输入生成的四则运算题个数(1-1000):";
        cin>>QstNum;
    }
    //是否有乘除法
    cout<<"是否有乘除法:(1/0)";
    cin>>IfIncMD;
    while(IfIncMD>1||IfIncMD<0)
    {
        cin>>IfIncMD;
    }

    //是否支持有括号
    cout<<"是否随机生成括号:";
    cin>>IfIncBrackets;
    while(IfIncBrackets!=1&&IfIncBrackets!=0)
    {
        cout<<"请输入1或0:(1随机生成括号,0不随机生成括号)";
        cin>>IfIncBrackets;
    }
    //整数数值范围
    cout<<"整数数值范围:(1000以内,100以内,10以内)";
    cin>>range;
    while(range!=10&&range!=100&&range!=1000)
    {
        cout<<"请输入10,100,或1000:";
        cin>>range;
    }
    //加减是否支持负数的存在
    cout<<"加减是否允许有负数的存在(输入1则允许,0则不允许):";
    cin>>IfNeg;
    while(IfNeg!=1&&IfNeg!=0)
    {
        cout<<"请输入1或0(输入1则允许否则不允许):"<<endl;
        cin>>IfNeg;
    }
    //除法是否允许有余数的存在
    cout<<"除法是否允许有余数的存在(输入1则允许,0则不允许):";
    cin>>IfRem;
    while(IfRem!=1&&IfRem!=0)
    {
        cout<<"请输入1或0(输入1则允许否则不允许):"<<endl;
        cin>>IfRem;
    }
    //整数除法是否允许有分数的存在
    cout<<"整数除法是否允许有分数的存在(输入1则允许,0则不允许):";
    cin>>IfFraction;
    while(IfFraction!=1&&IfFraction!=0)
    {
        cout<<"请输入1或0(输入1则允许否则不允许):"<<endl;
        cin>>IfFraction;
    }
}
void Digit(int i,string a[],int Location)//数字转变为字符
{
    if(i/100!=0)
    {
        a[Location]+=(char)(i/100+48);
    }
    if(i%100/10!=0)
    {
        a[Location]+=(char)(i%100/10+48);
    }
    a[Location]+=(char)(i%10+48);
}
void DealDigit(string a[],int p,int range,int IfNegative,int IfFraction,int x)
{
    int RandomNum1=(int)rand()%100/50;//是否产生负数的随机数
    int RandomNum2=(int)rand()%100/50;//是否产生分数的随机数
    x=(int)rand()%range;//分子
    int z=(int)rand()%range;//分母
    if(IfNegative==1)//随机生成数字
    {
        if(RandomNum1==1&&RandomNum2==1)//随机生成负分数
        {
            a[p]+='(';
            a[p]+='-';
            Digit(x,a,p);
            a[p]+='/';
            Digit(z,a,p);
            a[p]+=')';
        }
        else if(RandomNum1==1&&RandomNum2!=1)//负数
        {
            a[p]+='(';
            a[p]+='-';
            Digit(x,a,p);
            a[p]+=')';
        }
        else//数字默认为正数
        {
            Digit(x,a,p);
        }
    }
    else//正数
    {
        if(IfFraction==1)//随机生成正分数
        {
            if(RandomNum2==1)
            {
                a[p]+='(';
                Digit(x,a,p);
                a[p]+='/';
                Digit(z,a,p);
                a[p]+=')';
            }
        }
        else//默认为正数
        {
            Digit(x,a,p);
        }
    }
}
bool IfRepeated(int CurLocation,string a[])//是否重复
{
    for(int p=0;p<CurLocation;p++)
    {
        for(int q=0;a[p][q]!='=' && a[CurLocation][q]!='=';q++)
        {    
            if(a[p][q]!=a[CurLocation][q])
                p++;
            if(a[p][q]=='='&&a[CurLocation][q]=='=')
                    return true;
        }
    }
    return false;
}
void Deal()//生成题目
{
    for(int p=0;p<QstNum;p++)
    {
        int count=0;
        int FirstNum=0,SecNum=0;//生成的相邻的两个操作数
        int RandomNum1,RandomNum2,RandomNum3,RandomNum4;
        int OperandNum=(int)rand()%10/5+2;//操作数的个数,属于二元或三元运算
        int Brackets=(int)rand()%100/50;//随机生成括号
        int z;//分母
        if(Brackets==1&&count==0&&OperandNum>2&&IfIncBrackets==1)//判断是否生成括号
        {
            a[p]+="(";
            count++;
        }
        DealDigit(a,p,range,IfNeg,IfFraction,FirstNum);//生成第一个数

        for(int q=1;q<OperandNum;q++)
        {
            int Operator=(int)rand()%100/25;//操作符的范围
            if(IfIncMD==0)
                Operator/=2;//操作符范围设置只有"+-";
            switch(Operator)
            {
            case 0:
                a[p]+='+';
                DealDigit(a,p,range,IfNeg,IfFraction,SecNum);
                break;
            case 1:
                a[p]+='-';
                DealDigit(a,p,range,IfNeg,IfFraction,SecNum);
                break;
            case 2:
                a[p]+='*';
                DealDigit(a,p,range,IfNeg,IfFraction,SecNum);
                break;
            case 3:
                a[p]+='/';
                RandomNum1=(int)rand()%100/50;//是否产生负数的随机数
                RandomNum2=(int)rand()%100/50;//是否产生分数的随机数
                SecNum=(int)rand()%range;//分子
                z=(int)rand()%range;
                if(IfNeg==1)//随机生成数字
                {
                    if(RandomNum1==1&&RandomNum2==1)//随机生成负分数
                    {
                        a[p]+='(';
                        a[p]+='-';
                        Digit(SecNum,a,p);
                        a[p]+='/';
                        Digit(z,a,p);
                        a[p]+=')';
                    }
                    else if(RandomNum1==1&&RandomNum2!=1)//负数
                    {
                        a[p]+='(';
                        a[p]+='-';
                        Digit(SecNum,a,p);
                        a[p]+=')';
                    }
                    else//数字默认为正数
                    {
                        Digit(SecNum,a,p);
                        if(IfRem==0)
                        {
                            if(IfIncBrackets==0)//当不生成括号时
                            {
                                if(FirstNum%SecNum!=0)//除法有余数
                                {
                                    Digit(SecNum,a,p);
                                }
                            }
                        }
                    }
                }
                else//正数
                {
                    if(IfFraction==1)//随机生成正分数
                    {
                        if(RandomNum2==1)
                        {
                            a[p]+='(';
                            Digit(SecNum,a,p);
                            a[p]+='/';
                            Digit(z,a,p);
                            a[p]+=')';
                        }
                    }
                    else//默认为正数
                    {
                        Digit(SecNum,a,p);
                        if(IfRem==0)
                        {
                            if(IfIncBrackets==0)//当不生成括号时
                            {
                                if(FirstNum%SecNum!=0)//除法有余数
                                {
                                    Digit(SecNum,a,p);
                                }
                            }
                        }
                    }
                }
                break;
            }
            if(Brackets==1&&count==1&&q==1)
            {
                a[p]+=")";
            }
            FirstNum=SecNum;//将运算符左侧数置为FirstNum
        }
        a[p]+='=';
        //判断是否重复,重复则重新生成
        if(IfRepeated(p,a))
        {
            p--;
        }
    }
}
void Display()//打印题目
{
    int count1=0;
    int p;
    for(p=0;p<QstNum;p++)
    {
        cout<<a[p];
        count1++;
        cout<<endl;
    }
}
void main()//主函数
{
    srand((unsigned)time(NULL));
    int p;//程序运行选择器
    do
    {
        ParaSet();//参数设置
        Deal();//核心函数,生成算术题的
        Display();//打印题目
        //是否继续
        cout<<endl<<endl;
        cout<<"是否继续生成运算题(输入1则生成否则不生成):"<<endl;
        cin>>p;
        while(p!=1&&p!=0)
        {
            cout<<"请输入1或0(输入1则生成否则不生成):"<<endl;
            cin>>p;
        }
    }while(p==1);
    cout<<"OVER!"<<endl;
}

三,运行截图

四,项目计划日志

项目计划日志
日期/任务 课堂 编程 读书 博客 日总结
3.14 100min 30min 30min 0 130min
3.15   1h     1h
3.16   1h     1h
3.17   1h     1h
3.18   1h     1h
3.19   3h     3h
周总结 100 450min     550m

五,时间记录日志

时间记录日志
日期 开始时间 结束时间 净时间 活动 备注
3.14 8:00,19:00 10:00,19:30 130 上课,编程  
3.15 19:00 20:00 1h 编程  
3.16 19:00 20:00 1h 编程  
3.17 19:00 20:00 1h 编程  
3.18 19:00 20:00 1h 编程  
3.19 14:00 17:00 3h 编程  

六,缺陷记录日志

日期 编号 类型 引入 排除 修复时间 修复
3.16 1 数组溢出 编译   40min Y
3.19 2 一些测试例子输入后产生了不正确的结果 编译   1H N

七,仍然存在的问题

 一组参数如果输入否就会产生参与计算的数值丢失

原文地址:https://www.cnblogs.com/420Rock/p/5295966.html