定义一个中缀式类,可以求其后缀式以及计算其值

来源:互联网 发布:模拟位置什么软件 编辑:程序博客网 时间:2024/05/16 15:35

  1. /* infix.h
  2.  *定义一个中缀式类,可以求其后缀式,前缀式以及计算其值 
  3.  *缺点:如果算式中包含负数(如-x, x >=0),那么要写成0-|绝对值|(0-x ),才能正确求出其值; 
  4.  *          目前还没有完成求其前缀式的功能; 
  5.  *infix( string infix_str ) 构造函数,用infix_str赋值给m_infix_str 
  6.  *value(  ) 求给定中缀式的值,要先调用get_postfix(  )获得后缀式 
  7.  *show(  ) 显示中缀式,前缀式,后缀式(待实现) 
  8.  *get_postfix(  ) 获得后缀式 
  9.  *get_prefix(  ) 获得前缀式(待实现) 
  10.  * 
  11.  *功能函数: 
  12.  *bool strisnum( string str ) 判断一个字符串是否表示一个float或int 
  13.  *bool strisoper( string str ) 判断一个字符串是否表示一个运算符(*,/,%,+,-) 
  14.  *把一个strisnum( )返回值为真的string转变成一个数据 
  15.  *     if( strisnum( str ) ) 
  16.  *        { 
  17.                 //float number; 
  18.                 sscanf( str.c_str(  ),"%f",&number); 
  19.  *        } 
  20.  *本程序就是使用了istringstream,进行内存I/O来处理包含有数字的一串字符(后缀式) 
  21.  * 
  22.  *m_infix_str 存放中缀式 
  23.  *m_postfix_str 存放后缀式 
  24.  *m_prefix_str 存放前缀式 
  25.  * 
  26.  *      Made by winlin   2011.4.13 
  27.  *      pcliuguangtao@163.com 
  28.  *      gcc 4.4.5 
  29.  */ 
  30. #include <iostream> 
  31. #include <string> 
  32. using std::string; 
  33.  
  34. class infix 
  35. public
  36.     infix( string infix_str ); 
  37.  
  38.     float value(  ); 
  39.     void show(  ); 
  40.      
  41.     string get_postfix(  ); 
  42.     string get_prefix(  ); 
  43. private
  44.     string m_infix_str;     
  45.     string m_postfix_str; 
  46.     string m_prefix_str; 
  47. private
  48.     bool strisnum( string str ); 
  49.     bool strisoper( string str ); 
  50.      
  51. }; 

infix.cpp:

  1. #include "./infix.h" 
  2. #include <iostream> 
  3. #include <sstream> 
  4. #include <stack> 
  5. #include <string> 
  6. #include <cstdio>          //sscanf(  ) 
  7. #include <cctype>        //isalnum(  ) 
  8. using std::string; 
  9. using std::cout; 
  10. using std::stack; 
  11. using std::istringstream; 
  12.  
  13. infix::infix(string infix_str) 
  14.     m_infix_str=infix_str; 
  15.  
  16. string infix::get_postfix(  ) 
  17.     { 
  18.         char token;       //从中缀式中取字符 
  19.         char topToken;    //栈顶的字符 
  20.         stack<char> operStack;   //stroe the opreators 
  21.         const string BLANK=" "
  22.  
  23.         int size=m_infix_str.length(  ); 
  24.         forint i=0;i<size;++i ) 
  25.             { 
  26.                 token=m_infix_str[ i ]; 
  27.                 switch( token ) 
  28.                     { 
  29.                     case ' ':break
  30.                     case '('
  31.                         operStack.push( token ); 
  32.                         break
  33.                     case ')'
  34.                         { 
  35.                             while( 1 ) 
  36.                                 { 
  37.                                     if(! operStack.empty(  ) ) 
  38.                                         { 
  39.                                             topToken=operStack.top(  ); 
  40.                                             operStack.pop(  ); 
  41.                                             if( topToken=='(' ) break
  42.  
  43.                                             m_postfix_str.append( BLANK+topToken ); 
  44.                                              
  45.                                         } 
  46.                                 } 
  47.                         } 
  48.                         break
  49.                     case '+':    case '-'
  50.                     case '*':    case '/':   case '%'
  51.                         { 
  52.                             while( 1 ) 
  53.                                 { 
  54.                                     if( operStack.empty(  ) || operStack.top(  )=='(' || 
  55.                                         (( token=='*'||token=='/'||token=='%' )&&( operStack.top(  )=='+'||operStack.top(  )=='-' )) ) 
  56.                                         {   //if条件包含了*/和+-之间的优先级关系 
  57.                                             operStack.push( token ); 
  58.                                             break
  59.                                         } 
  60.                                     else 
  61.                                         { 
  62.                                             topToken=operStack.top(  ); 
  63.                                             operStack.pop(  ); 
  64.                                             m_postfix_str.append( BLANK+topToken ); 
  65.                                         } 
  66.                                 } 
  67.                         } 
  68.                         break
  69.                     default:      //operator datas 
  70.                     { 
  71.                         m_postfix_str.append( BLANK+token); 
  72.                         while(1) 
  73.                           { 
  74.                               if(isalnum( m_infix_str[ i+1 ] ) || m_infix_str[ i+1 ] =='.' ) 
  75.                               { 
  76.                                   i++; 
  77.                                   token=m_infix_str[ i ]; 
  78.                                   m_postfix_str.append(&token); 
  79.                               } 
  80.                               else 
  81.                                   break
  82.                                
  83.                           } 
  84.                     } 
  85.                 break
  86.                     }//switch 
  87.             }//for 
  88.  
  89.         //pop the release operator in the operator stack 
  90.        while( 1 ) 
  91.            { 
  92.                if( operStack.empty(  ) ) break
  93.                topToken=operStack.top(  ); 
  94.                operStack.pop(  ); 
  95.                if( topToken !='(' ) 
  96.                    { 
  97.                        m_postfix_str.append( BLANK+topToken); 
  98.                    } 
  99.                else 
  100.                    { 
  101.                        cout<<"ERROR in infix expression/n"
  102.                        break
  103.                    } 
  104.                 
  105.            } 
  106.        m_postfix_str.erase( 0,1 );   //delete the frist one blank,just for goodlooking 
  107.  
  108.        return m_postfix_str;   
  109.     } 
  110.  
  111. bool infix::strisnum( string str ) 
  112.     { 
  113.         int i; 
  114.         int size=str.length(  );  
  115.         for( i=0;i<size;++i ) 
  116.             { 
  117.                 if( isalnum( str[ i ] ) || str[ i ] =='.'); 
  118.                 else 
  119.                     return 0; 
  120.             } 
  121.         if( i==size ) 
  122.             return 1; 
  123.          
  124.     } 
  125.  
  126. bool infix::strisoper(string tempstr) 
  127.     { 
  128.         if(*tempstr.c_str(  )=='+'||*tempstr.c_str(  )=='-'|| 
  129.            *tempstr.c_str(  )=='*'||*tempstr.c_str(  )=='/' ||*tempstr.c_str(  )=='%'
  130.             return 1; 
  131.         else 
  132.             return 0; 
  133.     } 
  134.  
  135. float infix::value(  ) 
  136.     { 
  137.         stack<float> numstack;    //store the number and the middle result 
  138.         istringstream isstream( m_postfix_str,istringstream::in); 
  139.         string tempstr; 
  140.         float num_one,num_two; 
  141.         while( isstream>>tempstr) 
  142.             { 
  143.                 if( strisnum( tempstr) ) 
  144.                     { 
  145.                         sscanf( tempstr.c_str(  ),"%f", &num_one); 
  146.                         numstack.push( num_one ); 
  147.                     } 
  148.                 else if( ( int)numstack.size(  ) >1 && strisoper( tempstr )) 
  149.                     { 
  150.                           num_one=numstack.top(  ); 
  151.                           numstack.pop(  ); 
  152.                           num_two=numstack.top(  ); 
  153.                           numstack.pop(  ); 
  154.                           
  155.                           //WARNING: num_two must be the left opeator data 
  156.                         switch( *tempstr.c_str(  ) )          //const char* string::c_str(  )  
  157.                             { 
  158.                             case '+'
  159.                                 numstack.push( num_two+num_one); 
  160.                                 break
  161.                             case '-'
  162.                                 numstack.push( num_two-num_one); 
  163.                                 break
  164.                             case '*'
  165.                                 numstack.push( num_two*num_one); 
  166.                                 break
  167.                             case '/'
  168.                                 numstack.push( num_two/num_one); 
  169.                                 break
  170.                             case '%'
  171.                                 numstack.push( ( int )num_two% (int)num_one); 
  172.                                 break
  173.                             default
  174.                                 std::cerr<<"Unknow operator/n"
  175.                                 break
  176.                                  
  177.                             } //swutch 
  178.                     }//if-else-if 
  179.             }//while 
  180.         if((int)numstack.size(  )!=1 ) 
  181.             std::cerr<<"You have input a wrong formula/n"
  182.         return numstack.top(  ); 
  183.          
  184.     }//infix::value( ) 

 

 

 

 

 

  1. /*test.cpp*/
  2. #include "./infix.h" 
  3. #include <iostream> 
  4. #include <string> 
  5. using std::cout; 
  6. using std::cin; 
  7. using std::endl; 
  8. using std::string; 
  9.  
  10. int main(  ) 
  11.     { 
  12.         cout<<"******Attention:  -x  please change to ( 0-x ) !******/n"
  13.          
  14.         string str( "((0-1)+2)*3/4+3*( 238.123-46 )" );   //the result is 577.119 
  15.         infix one( str); 
  16.         string poststr=one.get_postfix(  ); 
  17.         cout<<poststr<<endl; 
  18.         cout<< one.value(  )<<endl; 
  19.  
  20.          
  21.         string strstr( "((0-1)+2)*3/4+3*( (0-0.5)-1 )" );   //the result is -3.75 
  22.         infix two( strstr); 
  23.         string ststr=two.get_postfix(  ); 
  24.         cout<<ststr<<endl; 
  25.         cout<< two.value(  )<<endl; 
  26.          
  27.         return 0; 
  28.          
  29.     } 

 

原创粉丝点击