第一种方法的逻辑是我比较理得清的

法一:

midS是存放中缀表达式的字符串,字符之间没有空格,suffiexS是存放后缀表达式的字符串,数字和字符之间都有空格

思路:

1.如果midS[i]是'(',直接压栈
2.如果是数字, 把完整数字复制到到midS中后加一个空格,读取完数字后要判断此时的midS[i]是否是'\0',如果是的话,break结束循环
3.如果是')',不停弹栈,把弹栈后的字符存到suffiexS中,加空格,注意要更新ch中所存栈顶元素的值,等遇到栈顶为'('时,停止弹栈,把'('出栈
4.如果栈顶字符优先级小于midS[i]或者栈为空,那么midS[i]直接进栈
5.如果栈顶字符优先级大于等于midS[i],一直弹出栈顶元素到suffiexS中(直到栈顶字符优先级小于midS[i]或者栈为空),每次存字符之后都要加空格,循环中注意更新ch中所存栈顶元素的值,'('的优先级最低,所以无论如何都不会在此比较下被弹出
6.退出循环后,判断栈是否为空,如果不为空的话,一直弹栈,将字符存入后缀表达式的字符串,加空格

  1 #include "SqStack.h"
  2 #include <cctype>
  3 
  4 double caculate(double a, char ch, double b)
  5 {
  6     switch (ch)
  7     {
  8     case '+':    return a + b;
  9     case '-':   return a - b;
 10     case '*':   return a * b;
 11     case '/':    return a / b;
 12     }
 13     return 0;
 14 }
 15 
 16 int get_priority(char ch)
 17 {
 18     int priority = 0;
 19     switch (ch)
 20     {
 21     case '+':
 22     case '-':
 23         priority = 1;
 24         break;
 25     case '*':
 26     case '/':
 27         priority = 2;
 28         break;
 29     case '(':
 30         priority = 0;
 31         break;
 32     }
 33     return priority;
 34 }
 35 
 36 /*中缀表达式转后缀表达式*/
 37 void transform(char* suffiexS, char* midS)
 38 {
 39     int i = 0;
 40     int cnt = 0;        //作为后缀表达式的字符栈的下标
 41     SqStack<char> Stack;
 42     char ch;
 43     cout << midS << endl;
 44     for (i = 0; midS[i] != '\0'; ++i)
 45     {
 46         /*先把'('和 '数字的情况考虑了*/
 47         if (midS[i] == '(')            //如果是'('则直接进栈
 48         {
 49             Stack.push(midS[i]);
 50             continue;
 51         }
 52 
 53         if (isdigit(midS[i]))
 54         {
 55             while (isdigit(midS[i]) && midS[i] != '\0')            //如果是数字,则整个赋值到midS中
 56                 suffiexS[cnt++] = midS[i++];
 57     
 58             suffiexS[cnt++] = ' ';                    //在数字后面加一个空格
 59             if (midS[i] == '\0')
 60                 break;
 61         }
 62         if (!Stack.IsEmpty())
 63             Stack.getTop(ch);
 64         if (midS[i] == ')')
 65         {
 66             Stack.getTop(ch);
 67             while (ch != '(')
 68             {
 69                 Stack.pop(ch);
 70                 suffiexS[cnt++] = ch;
 71                 suffiexS[cnt++] = ' ';
 72                 Stack.getTop(ch);
 73             }
 74             Stack.pop(ch);            //将'('弹出,但不存储
 75             continue;
 76         }
 77 
 78         //如果栈顶字符优先级大于等于midS[i]且栈不为空,弹出栈顶元素到midS中,加空格
 79         
 80         else if ((Stack.IsEmpty() || get_priority(ch) < get_priority(midS[i]))) 81         {
 82             Stack.push(midS[i]);
 83         }
 84             
 85         else if (get_priority(ch) >= get_priority(midS[i]))
 86         {
 87             while (get_priority(ch) >= get_priority(midS[i]) && !Stack.IsEmpty())
 88             {
 89                 Stack.pop(ch);
 90                 suffiexS[cnt++] = ch;
 91                 suffiexS[cnt++] = ' ';
 92                 Stack.getTop(ch);
 93             }
 94             Stack.push(midS[i]);            //把midS[i]入栈
 95         }
 96     }
 97     while (!Stack.IsEmpty())
 98     {
 99         Stack.pop(ch);
100         suffiexS[cnt++] = ch;
101     }
102     
103     suffiexS[cnt] = '\0';            //在后缀表达式末尾加上空字符
104     cout << suffiexS << endl;
105 }

 

输入1:

 2+3*(7-4)+8/4#
输入2:
 ((2+3)*4-(8+2))/5#
 
第二种方法:
 1 #include <iostream>
 2 #include <cctype>
 3 #include <stack>
 4 using namespace std;
 5 
 6 int getPriority(char ch)
 7 {
 8     int priority = 0;
 9     switch(ch)
10     {
11         case '+':
12             priority = 1;
13             break;
14         case '-':
15             priority = 1;
16             break;
17         case '*':
18             priority = 2;
19             break;
20         case '/':
21             priority = 2;
22             break;
23         case '(':
24             priority = 3;
25             break;
26         default:
27             priority = 0;
28             break;
29     }
30     return priority;
31 }
32 
33 
34 int main()
35 {
36     std::stack<char> S;
37     char ch;
38     cin >> ch;
39     while (ch != '#')
40     {
41         while (isdigit(ch))
42         {
43             cout << ch;
44             cin >> ch;
45             if(!isdigit(ch))        //ch 不是数字且不是'#', 表示完成了一个整型数据的输入,此时打印一个空格
46                 cout << " ";
47             
48 
49         }
50         if (ch == '#')
51             break;
52         if (ch == ')')                    //如果读入的字符是')',那么当栈顶元素不是‘(’时,一直输出栈顶元素
53         {
54             while (S.top() != '(')
55             {
56                 cout  << S.top()<< " ";
57                 S.pop();
58             }
59             S.pop();
60         }
61         else     //正常情况,将ch和栈顶字符比较优先级
62         {
63             while (!S.empty() && S.top() != '(' && getPriority(S.top()) >= getPriority(ch))
64             {
65                 cout << S.top()<< " " ;
66                 S.pop();
67             }
68             S.push(ch);
69 
70         }cin >> ch;
71     }
72 
73     while (!S.empty())
74     {
75         cout << S.top();
76         S.pop();
77         if (!S.empty())
78             cout << " ";
79     }
80 
81     return 0;
82 }

 

1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\xtgmath.h(214): warning C4602: #pragma pop_macro:“new”该标识符前面没有 #pragma push_macro
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\xtgmath.h(215): warning C4193: #pragma warning(pop) : 没有匹配的“#pragma warning(push)”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\xtgmath.h(216): warning C4161: #pragma pack(pop...) : 出栈的比入栈的多
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(23): error C2061: 语法错误: 标识符“abs”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(23): error C2059: 语法错误:“;”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(23): error C2061: 语法错误: 标识符“acos”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(23): error C2061: 语法错误: 标识符“asin”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(24): error C2061: 语法错误: 标识符“atan”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(24): error C2059: 语法错误:“;”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(24): error C2061: 语法错误: 标识符“atan2”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(24): error C2061: 语法错误: 标识符“ceil”
1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\cmath(25): error C2061: 语法错误: 标识符“cos”

若是switch单词写错了,则可能会出现上述错误。

 

最后是后缀表达式的计算:

 1 /*表达式求解*/
 2 double evaluation(char* suffiexS)
 3 {
 4     SqStack<int> Stack;
 5     int i = 0, num = 0;
 6     //cout << suffiexS << endl;
 7     int operand1, operand2, result;            //两个操作数和计算结果
 8     for (i = 0; suffiexS[i] != '\0'; ++i)
 9     {
10         if (isdigit(suffiexS[i]))
11         {
12             while (isdigit(suffiexS[i]))
13             {
14                 num = num * 10 + suffiexS[i] - '0';
15                 i++;
16             }
17             Stack.push(num);
18             num = 0;
19         }
20         
21         if (suffiexS[i] == ' ')
22             continue;
23         if (suffiexS[i] == '+')
24         {
25             Stack.pop(operand1);
26             Stack.pop(operand2);
27             result = operand1 + operand2;
28             Stack.push(result);
29 
30         }
31 
32         if (suffiexS[i] == '-')
33         {
34             Stack.pop(operand1);
35             Stack.pop(operand2);
36             result = operand2 - operand1;        //后pop出来的做被减数
37             Stack.push(result);
38         }
39 
40         if (suffiexS[i] == '*')
41         {
42             Stack.pop(operand1);
43             Stack.pop(operand2);
44             result = operand1 * operand2;
45             Stack.push(result);
46         }
47 
48         if (suffiexS[i] == '/')
49         {
50             Stack.pop(operand1);
51             Stack.pop(operand2);
52             result = operand2 / operand1;            //后pop出来的做被除数
53             Stack.push(result);
54         }
55         
56     }
57     Stack.pop(result);
58     return result;
59 }

中缀表达式的输入函数:

 1 /*输入中缀表达式*/
 2 void readExpr(char *midS)
 3 {
 4     char ch;
 5     int i = 0;
 6 
 7     while (cin >> ch && ch != '#')
 8         midS[i++] = ch;
 9     midS[i] = '\0';
10     
11 }