• 四则运算3


    
    

    设计思路:

    
    

    程序包含两部分,一部分是算式的生成,一部分是栈的使用用来判断和计算结果;

    
    

    算式生成,用的是调用子函数,因为每一个年级的出题要求不同所以对出题的范围加了条件限制;程序的结构框架大致为:

    
    

    程序开始将字符串数组宏定义,出题的数量和选择打印的方式都进行宏定义;

    
    

                For(         )

    
    

              {

    
    

                    For(      )

    
    

                    {

    
    

                        a> 产生左括号;(用switch…..case语句来判断;)

    
    

                         b> 产生数字:(其中,可以有分数小数和整数的产生)

    
    

                           其中不同年级选择的范围不同;

    
    

                        c>产生右括号;(右括号的产生是用左括号的数量来限制的)

    
    

                        d>产生运算符;运算符在输出最后一位数字之后就不会执行运算符产生的程序;)

    
    

    }

    
    

    }

    
    

    栈程序中:

    
    

    将算式生成的string类型的数组,转化为char类型的,读入到栈中,然后利用字符串优先级的判断,计算函数,我们的程序中不能出现负数所以在输出结果时加了结果判断;

    //组成员:禹慧慧 吕兰兰
    //四则运算,在前面的基础上实现判断正误  2016.3.19
    //我们的结果是如果选择dos界面,可以在界面上实现输入结果、判断正误与给出答案;如果选择txt,则打印出一份题目和一份答案
    //没有控制余数,都算成了小数
    #include<iostream>
    #include<ctime>
    #include<cmath>
    #include<sstream>
    #include<string>
    #include<fstream>
    #define MAX 1000
    using namespace std;
    
    int N;
    int way;
    string str[1000];
    ofstream outfile("questions.txt");
    ofstream outfile_1("answers.txt");
    
    
    class Input
    {
    public:
        Input()
        {
            for( int i = 0;i < MAX;i++ )
                Str_input[i] = '\0';
        }
        char Str_input[MAX];
        void inStr(string str11)
        {
            strcpy(Str_input,str11.c_str());
        }
    };
    
    /*输出模块*/
    class Output
    {
    public:
        Output()
        {
            result = 0;
        }
        void getRes( double res )
        {
            result = res;
        }
        void printRes(double &num_an)
        {
            num_an=result;
        }
    private:
        double result;
    };
    
    /*计算用的存储结构*/
    template <class Type>
    class STACK{                 
    private:
        Type base[MAX];
        int Size;
    public:
        STACK()
        {
            Size=0;
        };
        void push(Type a)     
        {
            base[Size]=a;
            Size++;
        }
        Type pop()           
        {
            return base[--Size];
        }
        int size()
        {return Size;}
    };
    
    
    /*计算的模块*/
    class jisuan
    {
    public: 
        bool shuhanshu(char);                 
        bool fuhanshu(char);                 
        int jckh(char);                  
        bool jcxsd(char *);              
        int pdyxj(char);                 
        double ToData(char*);             
        double Call(double,double,char);    
        int ppkh(char* buffer,int pos); 
        void Opr( STACK<char>&, STACK<double>&, int& ); 
        double Calculate(char*, double& );   
    
    };
    bool jisuan::shuhanshu(char ch)      
    {
        return ((ch>='0'&&ch<='9')||ch=='.')?true:false;
    }
    bool jisuan::fuhanshu(char ch)     
    {
        return (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#')?true:false;
    }
    int jisuan::jckh(char ch)
    {
        if(ch=='(')
            return 1;
        if(ch==')')
            return -1;
        return 0;
    }
    bool jisuan::jcxsd(char *ch)
    {
        int a=0;
        for(int i=0;i<strlen(ch);i++)
            if(ch[i]=='.')          
                a++;
        if(a>1)
            return false;
        return true;
    }
    int jisuan::pdyxj(char ch)          //符号的优先极别
    {
        switch(ch)
        {
        case '+':
            return 0;
        case '-':
            return 0;
        case '*':
            return 1;
        case '/':
            return 1;
        case '#':
            return 0;
        default:
            return -1;
        }
    }
    double jisuan::ToData(char* ch)   //将数字转化为数值
    {
        int i,j,sumn=0;
        double sum=0.0;
        if(!jcxsd(ch)) return 0.0;
        for(i=0;i<strlen(ch);i++)           
        {
            if(ch[i]!='.')
                sumn=sumn*10+(ch[i]-'0');
            else break;
        }
        if(i<strlen(ch))
            for(j=i+1;j<strlen(ch);j++)        
                sum=sum*10+(ch[j]-'0');
        sum /= pow(10.0,(double)(strlen(ch)-1-i));
        return (sum+sumn);                    
    }
    double jisuan::Call(double sum,double data,char ch)
    {
        double ans=0.0;
        switch(ch)
        {
        case '+':
            ans=sum+data;
            break;
        case '-':
            ans=sum-data;
            break;
        case '*':
            ans=sum*data;
            break;
        case '/':
            if( data != 0.0 )
                ans=sum/data;
            else
            {
                cout<<"程序出现除0错误,终止!\n";
                system("pause");
                exit(1);
            }
            break;
        case '#':
            return 0;
        default:ans=0.0;
            break;
        }
        return ans;
    }
    int jisuan::ppkh(char* buffer,int pos)     //利用栈找到匹配的括号
    {
        STACK<char> Temp;
        int i;
        for(i=pos;i<strlen(buffer);i++)
        {
            if(jckh(buffer[i])==1)
                Temp.push('0');
            if(jckh(buffer[i])==-1)
            {
                Temp.pop();
                if(Temp.size()==0) return i;
            }
        }
        return -1;
    }
    void jisuan::Opr(STACK<char>& symbol,STACK<double>& data,int& mark)
    {
        double sum;
        while(symbol.size()!=0)
        {
            char tem=symbol.pop();
            int temp=pdyxj(tem);
            symbol.push(tem);
            if(temp<mark)
                break;
            else{
                sum=Call(data.pop(),data.pop(),symbol.pop());
                data.push(sum);
            }
        }
    }
    double jisuan::Calculate(char* buffer,double& sum)   //字符串读入和各个函数调配
    {
        STACK<double> data;
        STACK<char> symbol;
        double ans;
        char temp[MAX];
        int ct=0,mark=0,tp=0;
        data.push(sum);
        while(ct<=strlen(buffer))
        {
            if(shuhanshu(buffer[ct]))            //如果是数字或小数点
            {
                while( ct < strlen(buffer) && shuhanshu(buffer[ct]) )
                    temp[tp++]=buffer[ct++];
                temp[tp]='\0';
                tp=0;                         //读到非数字也非小数为止
                ans=ToData(temp);             //把读到的字符串转化为数
                data.push(ans);
    
                if(ct==strlen(buffer))        //已经独到字符串末尾
                {
                    mark=0;
                    Opr(symbol,data,mark);    
                    sum=data.pop();           
                    return sum;               
                }
                else{
                    int mark=pdyxj(buffer[ct]);
                    Opr(symbol,data,mark);     //计算
                }
            }
            else if(fuhanshu(buffer[ct]))         //如果是运算符
                symbol.push(buffer[ct++]);     //运算符入symbol栈
            else
            {
                char BF[100];int k=0;          //如果都不是,则只能是括号
                while( jckh( buffer[ct] ) != 1 && ct <= strlen(buffer) )
                    BF[k++] = buffer[ct++];
                BF[k]='\0';
                if(jckh(buffer[ct])==1)       //一旦读到左括号,寻找它匹配的右括号
                {
                    int i,j;
                    char Temp[100];
                    for(i=ct+1,j=0;i<ppkh(buffer,ct);i++,j++)
                        Temp[j]=buffer[i];     //把这对括号中的字符串存入Temp
                    Temp[j]='\0';
                    data.push(Calculate(Temp,sum)); 
    
                    ct+=(strlen(Temp)+1);       
                    if(ct+1==strlen(buffer))   
                    {
                        mark=0;
                        Opr(symbol,data,mark);
                        sum=data.pop();
                        return sum;
                    }
                    else
                    {
                        mark=pdyxj(buffer[ct+1]); //不是的话继续计算
                        Opr(symbol,data,mark);
                    }
                    ct++;                           //读入下一个字符
                }
            }
        }
        return 0.;
    }
    int Expression(int grade,int N)
    {
    
        Input in;
        jisuan cl;
        Output out;
        double sum=0.0;
        double result;
        double answer;
        cout.precision(5);
        int random_a,random_b,random_c,random_e,random_f,random_g;
        int max,min;//整数
        int random_d;
        double random_h;
        
        //根据年级的不同选择每道题目的数的数量
        if(grade==2)
        {
            random_a=rand()%2+2;
            max=100;
            min=1;
        }
        if(grade==3)
        {
            random_a=rand()%3+2;
            max=500;
            min=1;
        }
        if(grade==4)
        {
            random_a=rand()%3+2;
            max=1000;
            min=1;
        }
        if(grade==5)
        {
            random_a=rand()%3+2;
            max=10000;
            min=1;
        }
        if(grade==6)
        {
            random_a=rand()%3+2;
            max=10000;
            min=1;
        }
        for(int j=0;j<N;j++)
        { 
            int flag=0;
            int count_p=0,count_q=0;//计算括号的数量
            for(int i=0;i<random_a;i++)
           {
            if(grade==2||grade==3||grade==4)
            {
                random_b=1;//只有整数计算
            }
            if(grade==5||grade==6)
            {
                random_b=rand()%3+0;
            }
            char str1[100];
            
            //左括号的产生
            if(random_a>2&&i<(random_a-1))
            {
                  random_d=rand()%4+0;
                  switch(random_d)//控制括号的产生
                  {
                    case 0:flag=0;break;
                    case 1:if(i!=(random_a-1)&&i<(random_a-2)){str[j]+='(';flag=1;count_q+=1;}break;
                    case 2:flag=0;break;
                    case 3:if(i!=(random_a-1)&&i<(random_a-2)){str[j]+='(';flag=1;count_q+=1;}break;
                    }
              }
                //random_b=rand()%3+0;//控制数字类型
                //数字的产生
                switch(random_b)
                {
                    
                case 0:
                       {
                        random_h=(rand()%100)/100.0;//小数
                           random_e=rand()%10+0;
                           random_h+=random_e;
                          stringstream ss;
                          ss<<random_h;
                           str[j]+=ss.str();
                       }
                       break;
                case 1:
                    {
                    random_c=rand()%(max-min+1)+min;//整数
                        itoa(random_c,str1,10);
                        str[j]+=str1;
                       } break;
                case 2:
                    {//分数
                    do{
                        random_f=rand()%20+1;
                        random_g=rand()%10+1;
                       }while(random_g==random_f);
                    int number=1;
                    int m;
                    if(random_g>random_f)
                    {    
                         m=random_f;
                    }
                    else 
                    { m=random_g;}
                    for(int k=2;k<m+1;k++)
                    {
                         if((random_g%k==0)&&(random_f%k==0))
                        {
                             number=k;
                        }
                    }
                    random_f=random_f/number;
                    random_g=random_g/number;
                    str[j]+='(';
                    if(random_g==1)
                    {
                         int n=0;
                         n=random_g;
                         random_g=random_f;
                         random_f=n;
                    }
                    itoa(random_f,str1,10);
                    str[j]+=str1;
                    str[j]+='/';
                    itoa(random_g,str1,10);
                    str[j]+=str1;
                    str[j]+=')';
                   }break;
                }
                //右括号的产生
               if((flag!=1)&&(count_p!=count_q))
               {
                   str[j]+=')';
                   count_p+=1;
               }
               if(i==(random_a-1))
               {
                   if(count_p<count_q)
                   {
                       for(int k=0;k<(count_q-count_p);k++)
                       str[j]+=')';
                   }
                }
            if(i!=(random_a-1))
            {
                random_b=rand()%4+0;
                switch(random_b)
                {
                case 0:{str[j]+='+';}break;
                case 1:{str[j]+='-';}break;
                case 2:{str[j]+='*';}break;
                case 3:{str[j]+='/';}break;
                }
            }
         }    
           
           in.inStr(str[j]);                              //输入模块
           out.getRes( cl.Calculate(in.Str_input,sum) ); //计算模块
           out.printRes(result);
           if (result<0)
           {
               j--;
           } 
           else
           {
               
               if(way==1)
               {
               cout<<str[j]<<"="<<endl;
               cout<<"请输入答案(6位有效数字):";
               cin>>answer;
               if (answer==result)
               {
                   cout<<"回答正确!"<<endl;
               }
               else
               {
                   cout<<"回答错误!"<<endl;
                   cout<<"正确结果为:"<<result<<endl;
               }
               }
               else
               {
                   outfile<<str[j]<<"=";
                   outfile<<endl;
                   outfile_1<<"正确结果为:"<<result;
                    outfile_1<<endl;
               }
           }
                
        }
        
        return 0;
    }    
    
    
        int main()
    {
        int grade;
        srand(time(0));
        cout<<"********************************************************************************"<<endl;
        cout<<"********************************************************************************"<<endl;
        cout<<"***************************欢迎使用小学四则运算出题系统*************************"<<endl;
        cout<<"********************************************************************************"<<endl;
        cout<<"*******作者:石家庄铁道大学   信1301-2     禹慧慧    吕兰兰    2016.3.19 *******"<<endl;
        cout<<"********************************************************************************"<<endl;
        cout<<"请选择打印方式:(0-TXT,1-DOS):";
        cin>>way;
        cout<<"********************************请选择年级**************************************"<<endl;
        cout<<"                                   2年级                                        "<<endl;
        cout<<"                                   3年级                                        "<<endl;
        cout<<"                                   4年级                                        "<<endl;
        cout<<"                                   5年级                                        "<<endl;
        cout<<"                                   6年级                                        "<<endl;
        cin>>grade;
            
        cout<<"请输入题目数量:";
        cin>>N;
        if(grade==2)
        {
        Expression(grade,N);
        }
        if(grade==3)
        {
            Expression(grade,N);
        }
        if(grade==4)
        {
            Expression(grade,N);
        }
        if(grade==5)
        {
            Expression(grade,N);
        }
        if(grade==6)
        {
            Expression(grade,N);
        }
        outfile.close();
        outfile_1.close();
     }






    项目计划日志(单位:h)
     

    听课

    编写程序

    阅读相关书籍

    网上查找资料

    日总计

    周一

    2

    0

    1

    0

    3

    周二

    0

    3

    0.5

    3.5

    周三

    0

    3

    1

    0

    4

    周四

    2

    6

    1

    9

    周五

    0

    4

    0

    2

    6

    周六

    0

    3

    1

    4

    周日

    周总计

    4

    19

    2

          4.5

    29.5

    
    
    
    

    时间记录日志:(单位:min:

    
    

    日期

    开始时间

    结束时间

    中断时间

    净时间

    活动

    备注

    星期一

    1400

    15:50

    10

    100

    听课

    软件工程

    20:00

    21:00

    0

    60

    看书

    构建之法

    星期二

    19:00

    19:30

    0

    30

    网上查找资料

    20:00

    23:00

    0

    180

    编程

    结对编程

    星期三

    15:00

    22:00

    180

    240

    编程和上网查找资料并且调试程序

    结对编程

    星期四

    14:00

    15:50

    10

    100

    听课

    软件工程

    16:00

    23:00

    60

    360

    编程

    结对编程

    星期五

    16:00

    21:00

    30

    270

    编程上网查找资料

    结对编程

    星期六

    19:00

    22:00

    0

    180

    编程和写博客

    结对编程

    
    

    缺陷记录日志:

    
    

    日期

    编号

    类型

    引入阶段

    排除阶段

    修复时间

    修复缺陷

    3/17

    1

    20

    编码

    调试

    20:00

    括号输出错误,运算不正确

    3/18

    2

    20

    编码

    调试

    19:00-21:00

    对栈的编写和运算结果

    3/19

    3

    20

    编码

    调试

    20:00-22:00

    括号的丢失和语法的错误。

     

     组成员吕兰兰网址:http://www.cnblogs.com/lvlan/

  • 相关阅读:
    第二章作业
    算法第五章作业及学期总结
    71 最大子列和问题 | 采用二分法+递归
    算法第一章作业
    算法第四章作业
    算法第三章作业
    Windows charles安装、配置及Android手机ca证书
    git出现fatal: Authentication failed for 'http:xxxx.git/''错误的解决办法
    如何用c#将十六进制转换成字符串?
    系统配置win7(64位),vs2010,没有注册类别 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
  • 原文地址:https://www.cnblogs.com/yhhzxcvbnm/p/5295739.html
Copyright © 2020-2023  润新知