zoukankan      html  css  js  c++  java
  • 栈计算中缀表达式

      1 #include<iostream>
      2 #include<stack> 
      3 #include<ctype.h>
      4 #include<math.h>
      5 #include<string>
      6 using namespace std;
      7 
      8 static char s1[] = "2*(3+5)+7/1-4";
      9 static char s2[] = "(1+2^3!-4)*(5!-(6-(7-(89-0!))))";
     10 
     11 // 运算符优先级数组 
     12 const char pri[9][9] = {
     13     {'>', '>', '<', '<', '<', '<', '<', '>', '>'}, 
     14     {'>', '>', '<', '<', '<', '<', '<', '>', '>'}, 
     15     {'>', '>', '>', '>', '<', '<', '<', '>', '>'}, 
     16     {'>', '>', '>', '>', '<', '<', '<', '>', '>'}, 
     17     {'>', '>', '>', '>', '>', '<', '<', '>', '>'}, 
     18     {'>', '>', '>', '>', '>', '>', ' ', '>', '>'}, 
     19     {'<', '<', '<', '<', '<', '<', '<', '=', ' '}, 
     20     {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, 
     21     {'<', '<', '<', '<', '<', '<', '<', ' ', '='},
     22 };
     23 
     24 // 运算符映射 
     25 int symbolIndex(char str)
     26 {
     27     if ('+' == str)
     28         return 0;
     29     else if ('-' == str)
     30         return 1;
     31     else if ('*' == str)
     32         return 2;
     33     else if ('/' == str)
     34         return 3;
     35     else if ('^' == str)
     36         return 4;
     37     else if ('!' == str)
     38         return 5;
     39     else if ('(' == str)
     40         return 6;
     41     else if (')' == str)
     42         return 7;
     43     else if ('' == str)
     44         return 8;
     45 }
     46 
     47 // 逻辑映射 
     48 int logicIndex(char str)
     49 {
     50     if('<' == str)
     51         return 1;
     52     else if('=' == str)
     53         return 2; 
     54     else if ('>' == str)
     55         return 3;
     56     return -1;
     57 }
     58 
     59 // 数学计算 
     60 float calculation(float i, char j, float k)
     61 {
     62     if ('!' == j)
     63     {
     64         float factorial = 1;
     65         for (int a = 1; a <= i; ++a)
     66         {
     67             factorial *= a;
     68         }
     69         return factorial;
     70     }
     71     else if ('+' == j)
     72     {
     73         return k + i;
     74     }
     75     else if ('-' == j)
     76     {
     77         return k - i;
     78     }
     79     else if ('*' == j)
     80     {
     81         return k * i;
     82     }
     83     else if ('/' == j)
     84     {
     85         return k / i;
     86     }
     87     else if ('^' == j)
     88     {
     89         return pow(k, i);
     90     }
     91 }
     92 
     93 // 计算表达式 
     94 float calculationStr(char* S)
     95 {
     96      int index = 0;
     97      stack<char>  symbolStack;  // 运算符栈 
     98      stack<float> numStack;     // 运算数栈 
     99      symbolStack.push('');
    100      
    101      while(!symbolStack.empty())
    102      {
    103          if(isalnum(S[index]))
    104          {     
    105              string str = "";
    106              while(isalnum(S[index]))
    107              {    
    108                  str += S[index++];    
    109             } 
    110             numStack.push(atof(str.c_str()));
    111         } 
    112         else
    113         {
    114             int i = symbolIndex(symbolStack.top());
    115             int j = symbolIndex(S[index]);
    116             char logic = pri[i][j];
    117             switch(logicIndex(logic))
    118             {
    119                 case 1:  // 当前运算符优先级大于栈顶时直接入栈 
    120                     symbolStack.push(S[index++]);
    121                     break;
    122                 case 2:  // 当前运算符优先级相等时去左括号和'/0'符 
    123                     symbolStack.pop();
    124                     index++;
    125                     break;
    126                 case 3:     // 当前运算符优先级小于栈顶时从栈中取数字并计算,将所得结果压入栈中 
    127                     char op = symbolStack.top();
    128                     symbolStack.pop();    
    129                     if('!' == op)
    130                     {
    131                         float num1 = numStack.top();
    132                         numStack.pop();
    133                         numStack.push(calculation(num1, op, 0));
    134                     }
    135                     else
    136                     {
    137                         float num1 = numStack.top();
    138                         numStack.pop();
    139                         float num2 = numStack.top();
    140                         numStack.pop();
    141                         numStack.push(calculation(num1, op, num2));
    142                     } 
    143                     break;     
    144             }
    145         }    
    146     } 
    147     
    148      return numStack.top();
    149 }
    150 
    151 int main()
    152 {
    153     cout<<calculationStr(s1)<<endl;
    154     cout<<calculationStr(s2)<<endl;
    155 } 

    优化点:

    1. 取运算符映射和逻辑映射写法过于丑陋;

    2. 从字符串中读取极可能多的数字的方式略显笨拙

    3. 字符串遍历时应摒弃index++的方式

    祝我无坚不摧,祝我百毒不侵,祝我狼心狗肺,祝我逍遥快活。
  • 相关阅读:
    小总结:fibonacci数的产生
    pick the stone game
    温故知新的错题训练:Coin game
    《博弈论的诡计》
    思维+博弈论:字符串操作
    一下午的编程思索录
    2018中国大学生程序设计竞赛
    温故知新的经典贪心题目:今年暑假不AC?
    2019-2020新学的一些东西(持续更新)
    【半平面交】JZOJ3297. 【SDOI2013】逃考
  • 原文地址:https://www.cnblogs.com/kpxy/p/14435664.html
Copyright © 2011-2022 走看看