zoukankan      html  css  js  c++  java
  • 实数四则运算表达式的计算,C++ 实现

      //一个能处理四则运算的程序,实现语言C++,支持嵌套括号,可以处理实数,源码见下面:
     
      1 #include<iostream>
      2 #include<cmath>
      3 using namespace std;
      4 const int MAX=1000;
      5 
      6 /*欢迎模块*/ 
      7 class Entry
      8 {
      9 public:
     10        static void welcome()
     11        {
     12             cout<<"欢迎来到本程序运算界面,该程序功能为根据表达式进行计算。\n"
     13                 <<"可以实现的计算为加减乘除四则运算," 
     14                 <<"支持小数运算,也支持负数的读入,但是要用括号将负数括起。\n"
     15                 <<"在下方输入处输入表达式,以回车结束。\n"
     16                 <<"=========================Felix============================\n\n"
     17                 <<"请输入表达式,回车结束:"
     18        }
     19 };
     20 
     21 /*输入模块*/
     22 class Input
     23 {
     24 public:
     25     Input()
     26     {
     27         forint i = 0;i < MAX;i++ )
     28             Str_input[i] = '\0';
     29     }    
     30     char Str_input[MAX];
     31     void inStr()
     32     {
     33         cin>>Str_input;
     34     }
     35 };
     36 
     37 /*输出模块*/
     38 class Output
     39 {
     40 public:
     41     Output()
     42     {
     43         result = 0;
     44     }    
     45     void getRes( double res )
     46     {
     47         result = res;
     48     }
     49     void printRes()
     50     {
     51         cout<<"这个表达式的结果为:"<<result<<endl;
     52     }
     53 private:
     54     double result;
     55 };
     56 
     57 /*计算用的存储结构*/
     58 template <class Type>        
     59 class STACK{                 //定义栈类
     60    private:
     61        Type base[MAX];
     62        int Size;
     63    public:
     64        STACK(){Size=0;};
     65        void push(Type a)     //入栈
     66        {
     67            base[Size]=a;
     68            Size++;
     69        }
     70        Type pop()            //出栈
     71        {
     72            return base[--Size];
     73        }
     74        int size()
     75        {return Size;}
     76 };
     77 
     78 
     79 /*计算的模块*/
     80 class Calculate_Cla
     81 {
     82 public:
     83     bool IsData(char);
     84     bool IsSym(char);
     85     int IsPar(char);
     86     bool Check(char *);
     87     int setPri(char);                 //判断符号的优先极别
     88     double ToData(char*);               //把字符串转化为数值
     89     double Call(double,double,char);    //具体按符号计算
     90     int GetMatch(char* buffer,int pos); //利用栈找到匹配的括号 
     91     void Opr( STACK<char>&, STACK<double>&int& ); //利用栈计算
     92     double Calculate(char*double& );   //字符串的读入及调配
     93 
     94 };
     95 bool Calculate_Cla::IsData(char ch)      //判断输入计算的数字是否为0-9
     96 {
     97     return ((ch>='0'&&ch<='9')||ch=='.')?true:false;
     98 }
     99 bool Calculate_Cla::IsSym(char ch)      //判断是否输入非法运算符
    100 {
    101     return (ch=='+'||ch=='-'||ch=='*'||ch=='/')?true:false;
    102 }
    103 int Calculate_Cla::IsPar(char ch)
    104 {
    105     if(ch=='('
    106        return 1
    107     if(ch==')'
    108        return -1
    109     return 0;
    110 }
    111 bool Calculate_Cla::Check(char *ch)
    112 {
    113     int a=0;
    114     for(int i=0;i<strlen(ch);i++)
    115         if(ch[i]=='.')
    116             a++;
    117         if(a>1)
    118             return false;
    119         return true;
    120 }
    121 int Calculate_Cla::setPri(char ch)          //符号的优先极别
    122 {
    123     switch(ch)
    124     {
    125     case '+':
    126         return 0;
    127     case '-':
    128         return 0;
    129     case '*':
    130         return 1;
    131     case '/':
    132         return 1;              
    133     default:
    134         return -1;
    135     }
    136 }          
    137 double Calculate_Cla::ToData(char* ch)   //将数字转化为数值 
    138 {
    139     int i,j,sumn=0;
    140     double sum=0.0;
    141     if(!Check(ch)) return 0.0;
    142     for(i=0;i<strlen(ch);i++)             //读入整数部分 
    143     {
    144         if(ch[i]!='.')
    145             sumn=sumn*10+(ch[i]-'0');
    146         else break;
    147     }
    148     if(i<strlen(ch))
    149         for(j=i+1;j<strlen(ch);j++)        //小数部分 
    150             sum=sum*10+(ch[j]-'0');
    151     sum /= pow(10.0,(double)(strlen(ch)-1-i)); 
    152     return (sum+sumn);                      //返回值 
    153 }
    154 double Calculate_Cla::Call(double sum,double data,char ch)
    155 {
    156     double ans=0.0;
    157     switch(ch)
    158     { 
    159     case '+':
    160         ans=sum+data;         
    161         break;
    162     case '-':
    163         ans=sum-data;
    164         break;
    165     case '*':
    166         ans=sum*data;
    167         break;
    168     case '/':
    169         if( data != 0.0 )
    170             ans=sum/data;
    171         else
    172         {
    173             cout<<"程序出现除0错误,终止!\n";
    174             system("pause");
    175             exit(1);
    176         }
    177         break;               
    178     default:ans=0.0;
    179         break;     
    180     }
    181     return ans;
    182 }
    183 int Calculate_Cla::GetMatch(char* buffer,int pos)     //利用栈找到匹配的括号 
    184 {
    185     STACK<char> Temp;
    186     int i;
    187     for(i=pos;i<strlen(buffer);i++)
    188     {
    189         if(IsPar(buffer[i])==1)
    190             Temp.push('0');
    191         if(IsPar(buffer[i])==-1)
    192         {
    193             Temp.pop();
    194             if(Temp.size()==0return i;
    195         }
    196     } 
    197     return -1;
    198 }
    199 void Calculate_Cla::Opr(STACK<char>& symbol,STACK<double>& data,int& mark)
    200 {
    201     double sum;
    202     while(symbol.size()!=0)
    203     {
    204         char tem=symbol.pop();
    205         int temp=setPri(tem);
    206         symbol.push(tem);
    207         if(temp<mark)
    208             break;
    209         else{
    210             sum=Call(data.pop(),data.pop(),symbol.pop());
    211             data.push(sum);
    212         }
    213     }
    214 }
    215 double Calculate_Cla::Calculate(char* buffer,double& sum)   //字符串读入和各个函数调配
    216 {
    217     STACK<double> data;
    218     STACK<char> symbol;
    219     double ans;
    220     char temp[MAX];
    221     int ct=0,mark=0,tp=0;
    222     data.push(sum);
    223     while(ct<=strlen(buffer))
    224     {
    225         if(IsData(buffer[ct]))            //如果是数字或小数点 
    226         {
    227             while( ct < strlen(buffer) && IsData(buffer[ct]) )
    228                 temp[tp++]=buffer[ct++];
    229             temp[tp]='\0';
    230             tp=0;                         //读到非数字也非小数为止 
    231             ans=ToData(temp);             //把读到的字符串转化为数 
    232             data.push(ans);      
    233             
    234             if(ct==strlen(buffer))        //已经独到字符串末尾 
    235             {
    236                 mark=0;
    237                 Opr(symbol,data,mark);    //计算
    238                 sum=data.pop();           //此时data栈中还剩一个数据,即是结果 
    239                 return sum;               //返回结果 
    240             }
    241             else{
    242                 int mark=setPri(buffer[ct]);
    243                 Opr(symbol,data,mark);     //计算 
    244             }
    245         }
    246         else if(IsSym(buffer[ct]))         //如果是运算符 
    247             symbol.push(buffer[ct++]);     //运算符入symbol栈 
    248         else
    249         {
    250             char BF[100];int k=0;          //如果都不是,则只能是括号
    251             while( IsPar( buffer[ct] ) != 1 && ct <= strlen(buffer) )
    252                 BF[k++= buffer[ct++];
    253             BF[k]='\0';      
    254             if(IsPar(buffer[ct])==1)       //一旦读到左括号,寻找它匹配的右括号 
    255             {
    256                 int i,j;
    257                 char Temp[100];
    258                 for(i=ct+1,j=0;i<GetMatch(buffer,ct);i++,j++)
    259                     Temp[j]=buffer[i];     //把这对括号中的字符串存入Temp 
    260                 Temp[j]='\0';
    261                 data.push(Calculate(Temp,sum)); //递归调用Calculate直到没有括号 
    262                            //然后开始计算,值层层返回最后将最终结果放入data栈 
    263                 ct+=(strlen(Temp)+1);       //跳过已经处理完的字符 
    264                 if(ct+1==strlen(buffer))    //这里考虑字符串以括号结尾的情况 
    265                 {
    266                     mark=0;
    267                     Opr(symbol,data,mark);
    268                     sum=data.pop();
    269                     return sum;
    270                 }
    271                 else
    272                 {
    273                     mark=setPri(buffer[ct+1]); //不是的话继续计算 
    274                     Opr(symbol,data,mark);
    275                 }
    276                 ct++;                           //读入下一个字符 
    277             }
    278         }
    279     } 
    280     return 0.;
    281 }
    282 
    283 
    284 /*检查输入表达式正确性模块*/
    285 class CheckStr
    286 {
    287 public:
    288     static int check( char *str )
    289     {
    290         int i;
    291         STACK<char> Temp;
    292         for( i = 0;i < strlen(str);i++ )
    293         {
    294             char t = str[i];
    295             if!(  (int(str[i]) <= 57 && int(str[i]) >= 48|| str[i]=='(' || str[i]==')' || str[i]=='*'
    296                 || str[i]=='+' || str[i]=='-' || str[i]=='/' || str[i]=='.')   )       //检测是否含有非法字符
    297                 return 2;
    298             else if( str[i]=='(' )   
    299                 Temp.push('0');
    300             else if( str[i]==')' )
    301             {
    302                 if( Temp.size()<=0 )                                      //检测括号是否匹配,右括号是否过多
    303                     return 1;
    304                 else
    305                     Temp.pop();
    306             }
    307         }
    308         if( Temp.size()!=0 )                                                //检测括号是否匹配,左括号是否过多
    309             return 1;
    310         return 0;
    311     }
    312 };
    313 
    314 int main()
    315 
    316     Entry::welcome();                           //欢迎模块
    317     double sum=0.0;
    318     cout.precision(12);
    319     
    320     Input in;
    321     Calculate_Cla cl;
    322     Output out;
    323 
    324     while(1)
    325     {
    326         in.inStr();                              //输入模块 
    327         int res = CheckStr::check(in.Str_input); //判断模块 
    328         if( res == 0 )
    329             break;
    330         else if( res == 1 )
    331             cout<<"输入字符串括号不匹配,请重新输入:\n";
    332         else if( res == 2 )
    333             cout<<"输入字符串有非法字符,请重新输入:\n";
    334         else
    335         {}
    336     }
    337     out.getRes( cl.Calculate(in.Str_input,sum) ); //计算模块
    338     out.printRes();                               //输出模块 
    339     system("pause");
    340     return 0;
    341 }
    342 
  • 相关阅读:
    (转)灵活运用 SQL SERVER FOR XML PATH
    Docker
    Springboot
    Redis
    Centos7.6在线安装mysql8.0.16
    Centos7.6安装jdk1.8
    Dubbo
    相关性检验
    逻辑回归和决策树上的一些区别
    postgresql 学习手册(客户端)
  • 原文地址:https://www.cnblogs.com/felixfang/p/1621318.html
Copyright © 2011-2022 走看看