//李妍 2015.3.12
//四则运算新 
#include<iostream>
#include<fstream> 
#include<iomanip>
#include<cmath>  
#include<vector>
#include<string>  
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
using namespace std;
#define random() (rand()%1000) 
const int MAX=1000;

  /*输入模块*/
  class Input
  {
  public:
      Input()
      {
          for( int i = 0;i < MAX;i++ )
              Str_input[i] = '\0';
      }
      char Str_input[MAX];
      void inStr()
      {
          cin>>Str_input;
      }
  };

  /*输出模块*/
  class Output
  {
  public:
      Output()
      {
          result = 0;
      }
      double getRes( double res )
      {
          result = res;        
          return 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.;
 }

string  i_s(int shuzi)
{
    int temp=abs(shuzi);
    char str[100];
    itoa(temp,str,10);
    string str1=str;
    return str1;
}

string zuhe (string str1,string str2,char x)
{
    string expression;
    expression=str1+x+str2;
    return expression;
}

 //是否有乘除法
char operator_random(int c1)
{
    char o;
    int c,c2;
    if(c1==0)
    {
        c2=2;
    }
    if(c1==1)
    {
        c2=4;
    }
    c= (rand() % 100)%c2;
    if (c == 0) o = '+';
    else if (c == 1) o = '-';
    else if (c == 2) o = '*';
    else o = '/';
    return o;
}

void main()
{
    srand((unsigned)time(NULL));//设置时间种子 ,以使程序每次得到的结果都不同 
    int mul_div,number,output_mode,value_range,num_1,num_2,plus_or_minus,jump,yushu,kuohao,score=0;
    double answer=0.0,solution;
    string str_1,str_2,temp;
    char operator_r;
    char storage[100];
    cout<<"    是否有乘除法?<0>没有   <1>有:";
    cin>>mul_div;
    cout<<"    有无括号?    <0>没有   <1>有:";
    cin>>kuohao;
    cout<<"    加减有无负数?<0>没有   <1>有:";
    cin>>plus_or_minus;
    cout<<"    除法有无余数?<0>没有   <1>有:";
    cin>>yushu;
    cout<<"    题目如何输出?<0>在文件中输出 ,<1>在此直接输出:";
    cin>>output_mode;
    cout<<"    请输入数值范围:";
    cin>>value_range;
    
    cout<<"    请输入题目的数量:";
    cin>>number;
    cout<<endl;

    string *expression=new string[number];//string expression[number];
    ofstream fout;
    if(output_mode==0)
    {
        fout.open("yunsuan.txt");
        fout<<number<<"道随机四则运算:"<<endl;
    }
    else
    {
        cout<<number<<"道随机四则运算:"<<endl;
    }

    for (int i = 0; i < number; i++)
    {
       num_1=random()%value_range+1;
       num_2=random()%value_range+1;
       int length;//运算式的长度   
       int j=num_1-num_2;
       int x=num_1%num_2;
       operator_r=operator_random(mul_div);
       length=random()%9+2;
       str_1=i_s(num_1);
       str_2=i_s(num_2);
       expression[i]=zuhe(str_1,str_2,operator_r);
       if(length>2)
       {
           for(length;length>2;length --)
           {
               operator_r=operator_random(mul_div);
               str_1=expression[i];
               if(kuohao==1)
               {
                   jump=random()%2;
                   if(jump==0)
                   {
                       str_1='('+str_1+')';
                   }
               }
               operator_r=operator_random(mul_div);
               num_2=random()%value_range+1;
               str_2=i_s(num_2);
               jump=random()%2;
               if (jump==0)
               {
                   temp=str_1;
                   str_1=str_2;
                   str_2=temp;
               }
               expression[i]=zuhe(str_1,str_2,operator_r);
              
           }   
       }
       if(output_mode==1)
       {
          
           strcpy(storage,expression[i].c_str());
         
            cout.precision(12);            //设置精度为12

            Input in;
            jisuan cl;
            Output out;
   
            answer=out.getRes( cl.Calculate(storage,answer) ); //计算模块

            if(plus_or_minus==0 )
            {    
                if(answer>0)
                {                
                    cout<<"    ("<<i+1<<")"<<expression[i]<<"="<<endl;                                        
                    cout<<"    输入结果:";                            
                    cin>>solution;                            
                    cout<<"    正确结果:"<<answer<<endl;                            
                    if(answer==solution)                        
                    {                            
                        score++;                                
                        cout<<"    正确!!!"<<endl;                                
                        cout<<endl;                            
                    }                        
                    else                    
                    {                            
                        cout<<"    很遗憾,错误!"<<endl;                            
                        cout<<endl;                            
                    }
                }    //如果结果小于0
                else
                {
                    i=i-1;
                }
            }
            else  //如果不要求加减无负数
            {
                cout<<"    ("<<i+1<<")"<<expression[i]<<"="<<endl;                                        
                    cout<<"    输入结果:";                            
                    cin>>solution;                            
                    cout<<"    正确结果:"<<answer<<endl;                            
                    if(answer==solution)                        
                    {                            
                        score++;                                
                        cout<<"    正确!!!"<<endl;                                
                        cout<<endl;                            
                    }                        
                    else                    
                    {                            
                        cout<<"    很遗憾,错误!"<<endl;                            
                        cout<<endl;                            
                    }
            }
       }   
       else
       {
           fout<<expression[i]<<"="<<endl;      
       }
    }
    if(output_mode==1)
    {
        cout<<"    得分:"<<score<<endl;
        cout<<endl;
    }
    
    if(output_mode==1) 
    {
        fout.close();
    }
} 

结对编程伙伴:李妍 20133099 博客地址:http://www.cnblogs.com/liyan-luckygirl/

四则运算<3>要求新加的功能是可以输入答题,并判断对错,最后得出最终得分。

我们利用栈来实现对算式的运算,从符号优先级入手,利用栈匹配,字符串读入等完成运算,最终得到结果。