栈计算中缀表达式

  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\0";
  9 static char s2[] = "(1+2^3!-4)*(5!-(6-(7-(89-0!))))\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 ('\0' == 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('\0');
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++的方式

posted @ 2021-02-23 14:05  梦涵的帅爸爸  阅读(100)  评论(0编辑  收藏  举报