zoukankan      html  css  js  c++  java
  • 四则运算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/

  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/yhhzxcvbnm/p/5295739.html
Copyright © 2011-2022 走看看