• 【链性栈】表达式求值


      1 //表达式求值      数据结构严蔚敏 表达式求值  代码实现
      2 #include<iostream>
      3 
      4 using namespace std;
      5 
      6 typedef struct _NODE_
      7 {
      8     int a;
      9     _NODE_* pNext;
     10 }Node,*pNode;
     11 
     12 
     13 int Precede(int cur,int sta);        //优先级判断 函数
     14 
     15 int EvaluateExpression();            //表达式求值 函数
     16 
     17 int Result(int i,int Opr,int j);    //结果计算 函数
     18     
     19 bool IsOper(int a);                    //运算符判读 函数
     20 
     21 
     22 class CStack                        //标准链性栈 类
     23 {
     24 private:
     25     pNode m_pHead;
     26     int m_iNodeCount;
     27 
     28 
     29 public:
     30     CStack()
     31     {
     32         m_pHead = NULL;
     33         m_iNodeCount = 0;
     34     }
     35     ~CStack()
     36     {
     37         
     38     }
     39 
     40     void InitStack();
     41 
     42     bool IsEmpty();
     43 
     44     bool PushStack(int a);
     45 
     46     bool PopStack(int& a);
     47 
     48     int GetTop();
     49 
     50     int GetLength();
     51 
     52     void DestroyStack();
     53 };
     54 
     55 int main()
     56 {
     57 
     58     cout<<EvaluateExpression()<<endl;
     59 
     60 
     61 
     62     return 0;
     63 }
     64 
     65 
     66 
     67 void CStack::InitStack()
     68 {
     69     if(!IsEmpty())
     70     {
     71         DestroyStack();
     72     }
     73     m_iNodeCount = 0;
     74 
     75     m_pHead = NULL;
     76 
     77 }
     78 
     79 
     80 
     81 bool CStack::IsEmpty()
     82 {
     83     if(m_iNodeCount == 0)
     84     {
     85         return true;
     86     }
     87 
     88     return false;
     89 }
     90 
     91 
     92 
     93 bool CStack::PushStack(int a)
     94 {
     95     pNode pNodeTemp = new Node;
     96 
     97     if(pNodeTemp != NULL)
     98     {
     99         pNodeTemp->a = a;
    100         pNodeTemp->pNext = NULL;
    101 
    102         if(m_pHead == NULL)
    103         {
    104             m_pHead = pNodeTemp;
    105         }
    106         else
    107         {
    108             pNodeTemp->pNext = m_pHead;
    109 
    110             m_pHead = pNodeTemp;
    111         }
    112 
    113         m_iNodeCount++;
    114 
    115         return true;
    116     }
    117 
    118     return false;
    119 }
    120 
    121 
    122 
    123 bool CStack::PopStack(int& a)
    124 {
    125     if(IsEmpty())
    126     {
    127         return false;
    128     }
    129     pNode pNodeDel = m_pHead;
    130 
    131     a = m_pHead->a;
    132 
    133     m_pHead = pNodeDel->pNext;
    134 
    135     delete pNodeDel;
    136 
    137     pNodeDel = m_pHead;
    138 
    139     m_iNodeCount--;
    140 
    141     return true;
    142 }
    143 
    144 int CStack::GetTop()
    145 {
    146     return m_pHead->a;
    147 }
    148 int CStack::GetLength()
    149 {
    150     return m_iNodeCount;
    151 }
    152 
    153 void CStack::DestroyStack()
    154 {
    155     pNode pNodeDel = m_pHead;
    156 
    157     while(pNodeDel != NULL)
    158     {
    159         m_pHead = pNodeDel->pNext;
    160 
    161         delete pNodeDel;
    162 
    163         pNodeDel = m_pHead;
    164 
    165         m_iNodeCount--;
    166     }
    167 }
    168 
    169 /***********************************/
    170 //判断优先级函数
    171 //先左后右
    172 //先乘除后加减
    173 //先括号内,再括号外
    174 /***********************************/
    175 
    176 //括号的优先级应该是最高的
    177 //然后是* / > + -
    178 //最后是遵循从左往右
    179 //+,-,*,/的优先级均 低于 '(' ,但是均高于')';
    180 
    181 int Precede(int cur,int sta)                    //cur 当前的运算符  sta 栈顶元素运算符
    182 {
    183     char f = 0;
    184     switch(cur)
    185     {
    186     case '+':                                    //判断前面的运算符 ( + -优先级一样 )
    187     case '-':
    188         {
    189             if(sta=='
    ' || sta=='(')            //若为空 或者 ( 就压栈
    190             {
    191                 f = '<';
    192             }
    193             else                                //否则,进行计算
    194             {
    195                 f = '>'; 
    196             }
    197 
    198             break;
    199         }
    200 
    201     case '*':
    202     case '/':
    203         {
    204             if(sta=='*'||sta=='/'||sta==')')    //遇到'*' , '/' 或')' 进行计算
    205             {
    206                 f = '>';
    207             }
    208             else                                //其他情况压栈
    209             {
    210                 f = '<';
    211             }
    212             
    213             break;
    214         }
    215     case '(':
    216         {
    217             if(sta==')')                        //不可能会存在  )(  这种情况 
    218             {
    219                 cout<<"Error"<<endl;
    220 
    221                 exit(0);
    222             }
    223             else
    224             {
    225                 f = '<';                        //遇到其他情况全部压栈
    226             }
    227             break;
    228         }
    229         
    230     case ')':
    231         {
    232             switch(sta)
    233             {
    234             case '(':
    235                 {
    236                     f = '=';        
    237                     break;
    238                 }
    239             case '
    ':
    240                 {
    241                     cout<<"Error."<<endl;
    242                     
    243                     exit(0);
    244                     break;
    245                 }
    246             default:                            //遇到此情况,均进行计算
    247                 {
    248                     f = '>';
    249                     break;
    250                 }
    251             }
    252 
    253             break;
    254         }
    255 
    256     case '
    ':                                    //'
    '一般为表达式结尾的标志了。
    257         {
    258             switch(sta)
    259             {
    260             case '
    ':
    261                 {
    262                     f = '=';
    263                     break;
    264                 }
    265             case '(':
    266                 {
    267                     cout<<"Error."<<endl;
    268                     
    269                     exit(0);
    270                 }
    271             default:
    272                 {
    273                     f = '>';
    274                     
    275                     break;
    276                 }
    277             }
    278 
    279             break;
    280         }
    281     }
    282 
    283     return f;
    284 }
    285 int EvaluateExpression()
    286 {
    287 
    288     CStack TableOper;                        //符号栈 (用来存运算符)
    289     CStack TableNum;                        //数组栈 (用来存数字)
    290 
    291     TableOper.InitStack();
    292     TableNum.InitStack();
    293 
    294     TableOper.PushStack('
    ');
    295 
    296     char a = 0;                                //存放当前的运算符
    297 
    298     int i = 0;                                //存放操作数1
    299     int j = 0;                                //存放操作时2
    300     int x = 0;                                //存放TablePer栈中的栈顶元素所代表的运算符
    301 
    302     int PreFlag = TableOper.GetTop();
    303     int NowFlag = TableOper.GetTop();
    304 
    305 
    306     a = getchar();                            //先接受一个字符
    307 
    308     x = TableOper.GetTop();
    309 
    310 
    311 
    312     while(a!='
    ' || x!= '
    ')
    313     {
    314 
    315 
    316 
    317         /**********判断是否是运算符**********/
    318         if(IsOper(a))        
    319         {
    320             char f = Precede(a,x);                            //进行优先级判断
    321         
    322             switch(f)
    323             {
    324                 case '<':                                    //如果当前运算符比栈中的运算符优先级低
    325                     {
    326                         TableOper.PushStack(a);                //那么将当前运算符a 压入栈
    327 
    328                         a = getchar();                        //接受下一个字符
    329 
    330                         NowFlag = TableOper.GetTop();        //NowFlag变为新压入栈的运算符
    331                     
    332                         break;
    333                     }
    334                 case '>':                                    //如果当前运算符比栈中的运算符优先级高
    335                     {
    336 
    337                         TableOper.PopStack(x);                //将TableOper(符号栈)栈顶的 运算符 弹出栈,准备作为运算符
    338 
    339                         PreFlag = TableOper.GetTop();        //PreFlag为前一个运算符
    340                         
    341                         TableNum.PopStack(i);                //将TableNum(数字栈)的两个待计算的操作数 弹出栈,并分别赋给i,j;
    342 
    343                         TableNum.PopStack(j);
    344 
    345                         TableNum.PushStack(Result(i,x,j));    //    将计算完毕的结果再压栈压回TableNum中
    346 
    347                         break;
    348 
    349                     }
    350                 case '=':                                    //如果优先级相等
    351                     {
    352 
    353                         TableOper.PopStack(x);                //TableOper中的栈顶 运算符 弹栈 给 x, 作为 待 操作的运算符
    354                     
    355                         a = getchar();                        //接受新的字符
    356 
    357                         break;
    358                     }
    359             }
    360         }
    361 
    362         /**********判断是否是数字**********/
    363         else if(a >= '0' && a <= '9')
    364         {
    365             if(PreFlag == NowFlag)                            //如果前后的符号标记相等,(即意味着一直在输入数字,如 12 + 34,这里的12 = 1*10 + 2)
    366             {
    367                 if(!TableNum.IsEmpty())                        //如果当前的TableNum 数字栈 不为空
    368                 {
    369                     int Temp = 0;
    370 
    371                     TableNum.PopStack(Temp);                //先将前一个被压入TableNum栈的数字弹出给Temp  (如弹出1)
    372 
    373                     Temp *= 10;                                //Temp *= 10                                  (Temp = 10)
    374     
    375                     Temp = Temp + a - 48;                    //Temp 再加上现在的a ,再进去48                  (Temp = 10 + 'a' -48 = 10 + 50 - 48 = 12)
    376 
    377                     TableNum.PushStack(Temp);                //再将Temp 压回到 数字栈        
    378     
    379                     a = getchar();                            //再读入字符
    380                 }
    381 
    382 
    383                 else                                        //反之,若为空,也就是数字栈中没有数
    384                 {
    385                     TableNum.PushStack(a-48);                //直接将a-48 压入 数字栈
    386 
    387                     a = getchar();                            //再读入字符
    388                 }    
    389             }
    390 
    391             else                                            //如果前后的符号标记不相等,(即意味着,输入的数字中间有间隔 运算符 如 1 + 2)
    392             {
    393                 PreFlag = NowFlag;                            //把PreFlag 置为 当前的 运算符
    394 
    395                 TableNum.PushStack(a-48);                    //直接将a-48 压入 数字栈
    396 
    397                 a = getchar();                                //再读入字符
    398             
    399             }
    400         }
    401 
    402     /**********都不是,说明输入的表达式有误**********/
    403         else
    404         {
    405             cout<<"error"<<endl;
    406 
    407             exit(0);
    408 
    409         }
    410 
    411         x = TableOper.GetTop();
    412         
    413     }
    414 
    415                     
    416     int ans = 0;                                            //定义一个answer,作为结果返回
    417 
    418     TableNum.PopStack(ans);
    419 
    420 
    421     return ans;
    422 }
    423 
    424 
    425 
    426 
    427 bool IsOper(int a)                                            //判断是否是运算符,这里只是 + - * / ( ) 
    
    428 {
    429     switch(a)
    430     {
    431     case '+':
    432     case '-':
    433     case '*':
    434     case '/':
    435     case '(':
    436     case ')':
    437     case '
    ':
    438         {
    439             return true;
    440         }
    441 
    442     default:
    443         {
    444             return false;
    445         }
    446     }
    447 }
    448 
    449 int Result(int i,int Opr,int j)                                //计算两个数直接的运算结果
    450 {
    451     switch(Opr)
    452     {
    453     case '+':
    454         return i+j;
    455     case '-':
    456         return j-i;
    457 
    458     case '*':
    459         return j*i;
    460     case '/':
    461         return j/i;
    462 
    463     default:
    464         return-1;
    465     }
    466 
    467 }
  • 相关阅读:
    植物-常见植物:苍耳草
    Linux 服务的加入删除,自己主动执行及状态
    HTML标签列表
    cocos2d js ClippingNode 制作标题闪亮特效
    被AppStore拒绝理由(一)
    開始学习hadoop
    改动mysqlpassword
    hdu 1874 畅通project续
    发现百度开源一个好东西,Echarts统计报表前段框架
    一个基于cocos2d-x 3.0和Box2d的demo小程序
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3391159.html
Copyright © 2020-2023  润新知