四则运算3

Posted GloryYT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算3相关的知识,希望对你有一定的参考价值。

本次作业的题目:

在四则运算2的基础上,再添加一些条件,总共要求满足如下条件:

1.题目避免重复。

2.可制定。(数量/打印方式)

3.可以控制下列参数:

  • 是否有乘除法
  • 是否有括号(最多可支持10个数参与计算)
  • 数值范围
  • 加减有无负数
  • 乘除有无余数

(新要求)

4.学生写的程序必须能判定用户的输入答案是否正确

5.程序必须能处理混合四则运算

PS:连续的减法和除法,应该遵循做结合的规定;连续除法要打括号。

设计思想:

  1.因为这次是结对开发,两个人结对,并且再上一次的程序基础上进行拓展,所以比较了一下各自的程序,选出较优秀的那一个。

  2.由于要完成的功能非常多,可以划分多个模块实现,便于多个功能组合。

  3.第一个模块就是出现连除的情况,我们程序是随机出现括号的,如果出现连除的情况,必须在后方添加括号。

  4.括号的实现,利用整型转化成字符串型来进行解决,括号随机出现左边或者右边,保存在数组之内。

  5.实现真分数以及真分数的运算,运算方式直接利用分数的加减乘除运算规则来实现。

  6.结果的验证,将四则运算算式转化成字符串,利用压栈入栈的数据结构计算四则运算表达式,正确的结果与输出入的结果进行比较,得出答案是否正确。

代码:

 

//随机生成四则运算表达式 杨超群 杨涛 2016.3.12
#include<iostream>
#include<string>
#include<time.h>
#include <stdio.h>
#include<fstream>
#include<cmath>
#include<sstream>
#include<strstream>
#include<math.h>
#include<iomanip>
#define MAX 100
#define False 0
#define True 1
using namespace std;
typedef string SelemType;
using namespace std;
string str1[4]={"+","-","*","/"};                        //运算符数组,存储+ - * /
int n,m;
int num[6];                                                //随机生成的操作数
char str2[25];                                             //整数转化为的字符数组
char str3[25];                                             //整数转化为的字符数组
string str4[100];
int OperatorNum[1000];                                    //运算符数组,每生成一个运算符存进数组
typedef struct{
    SelemType *base;
    SelemType *top;
    int stacksize;
}Sqstack;
void InitStack(Sqstack &s)                 //栈的初始化
{
     s.base=new SelemType[MAX];
     if(!s.base)exit(1);
     s.top=s.base;
     s.stacksize =MAX;
}
void Push(Sqstack &s,SelemType e)          //压入
{
    if(s.top-s.base==s.stacksize)
        exit(1);
    *s.top++=e;
}
void Pop(Sqstack &s,SelemType &e)          //弹出
{
     if(s.top==s.base)
        exit(1);
     e=*--s.top;
}
SelemType GetTop(Sqstack &s)          //取顶
{
     if(s.top==s.base)
         exit(1);
     return *(s.top-1);
}
int In(SelemType ch)                        //判断是否为运算符
{
    if(ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="("||ch==")"||ch=="#")
        return True;
     else
        return False;
}
SelemType Operate(SelemType a1,SelemType theta,SelemType b1)                          //计算
{
    stringstream ss;
    SelemType c1;
    double m1,m2;
    double m3,m4;
    m1=atof(a1.c_str());
    m2=atof(b1.c_str());
    if(theta=="+")
        m3=m1+m2;
    else if(theta=="-")
        m3=m1-m2;
    else if(theta=="*")
        m3=m1*m2;
    else if(theta=="/")
        m3=m1/m2;
    m4=double((int)(m3*100))/100.0;
    ss<<m4;
    ss>>c1;
    return c1;
}
char Precede(string theta1,string theta2)                     //运算符的计算顺序判断
{
    char chx;
    if(theta1=="+")
    {
        if(theta2=="*"||theta2=="/"||theta2=="(")
            chx = \'<\';
        else
            chx = \'>\';   
    }
    else if(theta1=="-")
    {
        if(theta2=="*"||theta2=="/"||theta2=="(")
            chx = \'<\';
        else
            chx = \'>\';   
    }
    else if(theta1=="*")
    {
        if(theta2=="(")
            chx = \'<\';
        else
            chx = \'>\';   
    }
    else if(theta1=="/")
    {
        if(theta2=="(")
            chx = \'<\';
        else
            chx = \'>\';   
    }
    else if(theta1=="(")
    {
         if(theta2==")")
             chx = \'=\';
         else if(theta2=="#")
             chx=\'$\';
         else
            chx = \'<\';   
    }
    else if(theta1==")")
    {
        if(theta2=="(")
            chx = \'$\';
        else
            chx = \'>\';   
    }
    else if(theta1=="#")
    {
        if(theta2=="#")
            chx = \'=\';
        else if(theta2==")")
            chx=\'$\';
        else
            chx = \'<\';   
    }
     return chx;
}
string TiQuString(string str,int &i)
{
       string ch;
    char *q;
    string p;
    p=str;
    q=&p[i];
    ch=ch+*q;
    if((*q>=\'0\')&&(*q<=\'9\'))
    {
        i++;
        int j=1;
        while((*(q+j)>=\'0\')&&(*(q+j)<=\'9\'))
        {
            ch=ch+*(q+j);
            j++; 
        }
        i=i+j-1;    
    }
    else
    {
        ch=*q;
        i++;
    }
    return ch;
}
string OPeration(string str)
{

     string str1;
     str1=str+"#";
     int i=0;
     string ch;
     ch=TiQuString(str1,i);
     SelemType theta,x1,a1,b1;
     Sqstack OPND,OPTR;
     InitStack(OPTR);
     InitStack(OPND);
     Push(OPTR,"#");
     while(ch!="#"||GetTop(OPTR)!="#")
     {
         int f;
         f=In(ch);
         if(f!=True)
         {
             Push(OPND,ch);
             ch=TiQuString(str1,i);
         }
         else
            {
                switch(Precede(GetTop(OPTR),ch))
                {
                case \'<\':
                    {
                        Push(OPTR,ch);
                        ch=TiQuString(str1,i);
                        break;
                    }
                case \'>\':
                    {
                        Pop(OPTR,theta);
                        Pop(OPND,b1);Pop(OPND,a1);
                        Push(OPND,Operate(a1,theta,b1));
                        break;
                    }
                case \'=\':
                    {
                        Pop(OPTR,x1);
                        ch=TiQuString(str1,i);
                        break;
                    }
                case \'$\':
                    {
                        cout<<"该表达式有错";
                        break;
                    }
                default:break;
                }
         }
     }
     return GetTop(OPND);

} 
void Input(int n,int p,int min,int max,int &j,int &q)
{
    int num1,num2,num3,num4,num5;                        //随机数
    int c=0;                                             //指向第一个运算符数组的下标
    int s=0;                                             //括号的个数
    string str;
    ofstream outfile;    
    outfile.open("a.txt",ios::app);                  
    if(!outfile)
    {
        cerr<<"OPEN ERROR!"<<endl;
        exit(0);
    }
    num1=rand()%(max-min+1)+min;
    num2=rand()%(max-min+1)+min;
    num3=rand()%4;                                       //随机数指向运算符数组的下标
    itoa(num1,str2,10);                                  //整数转化为字符数组
    itoa(num2,str3,10);                                   //整数转化为字符数组
    str=str2+str1[num3]+str3;                             //生成表达式
    OperatorNum[c]=num3;                                  //当前生成的符号存入OperatorNum数组里
    c++;
    n=n-2;                       //消耗了两个操作数
    while(n!=0)                 //当n不等于0时,循环生成str,即表达式+符号+表达式的形式
    {    
        num4=rand()%2;
        if(num4==0)             //上一个str放在符号的左边
        {
            num5=rand()%2;
            if(s<=3)
            {
                if(num5==0)            //上一个str不加括号
                {
                    num3=rand()%4;
                    OperatorNum[c]=num3;
                    c++;
                    num1=rand()%(max-min+1)+min;
                    itoa(num1,str2,10);
                    if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
                        str="("+str+")"+str1[num3]+str2;
                    else
                        str=str+str1[num3]+str2;
                }
                else                           //上一个str加括号
                {
                    num3=rand()%4;
                    num1=rand()%(max-min+1)+min;
                    itoa(num1,str2,10);
                    str="("+str+")"+str1[num3]+str2;
                    s++;
                }
            }
            else
            {
                num3=rand()%4;
                OperatorNum[c]=num3;
                c++;
                num1=rand()%(max-min+1)+min;
                itoa(num1,str2,10);
                if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
                    str="("+str+")"+str1[num3]+str2;
                else
                    str=str+str1[num3]+str2;
            }
        }
        else                              //上一个str放在符号的右边
        {
            num5=rand()%2;
            if(s<=3)
            {
                if(num5==0)                    // 上一个str不加括
                {
                    num3=rand()%4;
                    OperatorNum[c]=num3;
                    c++;
                    num1=rand()%(max-min+1)+min;
                    itoa(num1,str2,10);
                    if((num3==3)&&(OperatorNum[c-2]==3))
                        str=str2+str1[num3]+"("+str+")";
                    else
                        str=str2+str1[num3]+str;
                }
                else                         //上一个str加括号
                {
                    num3=rand()%4;
                    num1=rand()%(max-min+1)+min;
                    itoa(num1,str2,10);
                    str=str2+str1[num3]+"("+str+")";
                    s++;
                }
            }
            else
            {
                num3=rand()%4;
                OperatorNum[c]=num3;
                c++;
                num1=rand()%(max-min+1)+min;
                itoa(num1,str2,10);
                if((num3==3)&&(OperatorNum[c-2]==3))
                    str=str2+str1[num3]+"("+str+")";
                else
                    str=str2+str1[num3]+str;
            }
        }
        n--;                                //消耗一个操作数
    }
    string result1,result2;               //result1表示用户输入的答案,result2表示程序计算的结果
    str4[p]=str;                         //把str存入字符串数组str4中
    for(int i=0;i<p;i++)                 //查询四则运算式是否有重复
        if(str4[i]==str4[p])
             Input(m,p,min,max,j,q);
    cout<<str4[p]<<"=";
    result2=OPeration(str);                  //计算四则表达式
    cin>>result1;
    if(result1==result2)                        //判断结果是否正确
    {
        cout<<"计算正确";
        j++;
    }
    else
    {
        cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2;
        q++;
    }
    outfile<<str4[p]<<endl;
    cout<<endl;
}
void Input1(int n,int p,int min,int max,int &j,int &q)
{
    int num1,num2,num3,num4;
    int c=0;
    int s=0;
    string str;
    ofstream outfile;
    outfile.open("a.txt",ios::app);                  
    if(!outfile)
    {
        cerr<<"OPEN ERROR!"<<endl;
        exit(0);
    }
    num1=rand()%(max-min+1)+min;
    num2=rand()%(max-min+1)+min;
    num3=rand()%4;
    itoa(num1,str2,10);
    itoa(num2,str3,10);
    str=str2+str1[num3]+str3;
    OperatorNum[c]=num3;
    c++;
    n=n-2;
    while(n!=0)                 //当n不等于0时,循环生成str,即表达式+符号+表达式的形式
    {    
        num4=rand()%2;
        if(num4==0)             //上一个str放在符号的左边
        {
            num3=rand()%4;
            OperatorNum[c]=num3;
            c++;
            num1=rand()%(max-min+1)+min;
            itoa(num1,str2,10);
            if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
                str="("+str+")"+str1[num3]+str2;
            else
                str=str+str1[num3]+str2;
        }
        else                              //上一个str放在符号的右边
        {
            num3=rand()%4;
            OperatorNum[c]=num3;
            c++;
            num1=rand()%(max-min+1)+min;
            itoa(num1,str2,10);
            if((num3==3)&&(OperatorNum[c-2]==3))
                str=str2+str1[num3]+"("+str+")";
            else
                str=str2+str1[num3]+str;
        }        
        n--;
    }
    string result1,result2;
    str4[p]=str;                         //把str存入字符串数组str4中
    for(int i=0;i<p;i++)                 //查询四则运算式是否有重复
        if(str4[i]==str4[p])
             Input(m,p,min,max,j,q);
    cout<<str4[p]<<"=";
    result2=OPeration(str);
    cin>>result1;
    if(result1==result2)
    {
        cout<<"计算正确";
        j++;
    }
    else
    {
        cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2;
        q++;
    }
    outfile<<str4[p]<<endl;
    cout<<endl;
}
void sort(int min,int max){                      //生成四个随机数并排序
    num[0]=rand()%(max-min+1)+min;
    num[1]=rand()%(max-min+1)+min;
    num[2]=rand()%(max-min+1)+min;
    num[3]=rand()%(max-min+1)+min;
    for(int i=0;i<4;i++){
        for(int j=0;j<i;j++){ 
            if(num[i]>num[j])
            {
                int temp=0;
                temp=num[i];
                num[i]=num[j];
                num[j]=temp;
            }
        }
    }    
}
void sort1(int min,int max)                                    //生成两个随机数,并排序
{                     
    num[4]=rand()%(max-min+1)+min;
    num[5]=rand()%(max-min+1)+min;
    for(int i=4;i<6;i++){
        for(int j=4;j<i;j++){ 
            if(num[i]>num[j])
            {
                int temp=0;
                temp=num[i];
                num[i]=num[j];
                num[j]=temp;
            }
        }
    }    
}
void Simplification(int &m,int &n)                                    //真分数化简
{
       int x,y,i,p;                                                     //公约数p
    if(m>=n)
    {
        x=n;
        y=m;
    }
    if(m<n)
    {
        x=m;
        y=n;
    }
    for(i=x;i>0;i--)
    {
        if(x%i==0&&y%i==0)
        {
            p=i;
            break;
        }
    }
    m=m/p;
    n=n/p;
}
void Input2(int n,int p,int min,int max,int &j,int &q)
{
    int num3,num4,s=0;
    string str,strr2,strr3,str5,str6,str7,str8,str9;
    stringstream ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8;
    ofstream outfile;
    outfile.open("a.txt",ios::app);                  
    if(!outfile)
    {
        cerr<<"OPEN ERROR!"<<endl;
        exit(0);
    }
    num3=rand()%4;
    sort(min,max);
    Simplification(num[0],num[3]);
    Simplification(num[1],num[2]);
    ss1<<num[0];
    ss1>>strr2;
    ss2<<num[1];
    ss2>>strr3;
    ss3<<num[2];
    ss3>>str5;
    ss4<<num[3];
    ss4>>str6;
    if((str5!=strr3)&&(str6!=strr2))                                             //避免生成分子分母相等的表达式
        str="("+str5+"/"+strr3+")"+str1[num3]+"(Python 3学习笔记

如何在 python 中并行化以下代码片段?

20个简洁的 JS 代码片段

获取 badarith,[erlang,'+',[error,0],[],同时使用 Erlang 片段在 TSUNG 中执行算术运算

20194626 自动生成四则运算题第一版报告

20个简洁的 JS 代码片段