1 //逆波兰数实现表达式运算
2 #include<iostream>
3 #include<string>
4 #include<stdlib.h>
5 using namespace std;
6
7 //链栈
8 template<class T>
9 struct LinkStack {
10 T num;
11 struct LinkStack* next;
12 };
13
14 template<class T>
15 void InitStack(LinkStack<T>*& L) {
16 L = (LinkStack<T>*)malloc(sizeof(LinkStack<T>));
17 L->next = NULL;
18 }
19
20 template<class T>
21 void Push(LinkStack<T>*& L, T e) {
22 LinkStack<T>* p = (LinkStack<T>*)malloc(sizeof(LinkStack<T>));
23 p->num = e;
24 p->next = L->next;//头插法入栈
25 L->next = p;
26 }
27
28 template<class T>
29 void Pop(LinkStack<T>*& L, T& x) {
30 LinkStack<T>* p = L->next;
31 x = p->num;
32 L->next = p->next;
33 delete p;
34 }
35
36 template<class T>
37 bool isEmpty(LinkStack<T>* L) {
38 return L->next == NULL;
39 }
40
41 template<class T>
42 char getTop(LinkStack<T>* L) {
43 if(L->next !=NULL)return L->next->num;//?
44
45 }
46
47 void calcu(LinkStack<int> *&nums,LinkStack<char> *&opech) {
48 int left, right, result;
49 char oper;
50 Pop(nums, right);
51 Pop(nums, left);
52 Pop(opech, oper);
53 if (oper == '+')result = left + right;
54 if (oper == '-')result = left - right;
55 if (oper == '*')result = left * right;
56 if (oper == '/')result = left / right;
57 Push(nums, result);
58 }
59 //逆波兰算法实现
60 int Polish(const char s[], int len) {
61 LinkStack<int> *nums;
62 LinkStack<char> *opech;
63 InitStack(nums); InitStack(opech);
64 int count = 0;
65 while (!isEmpty(opech) || count < len) {
66 //两种情况:当字符串扫描完时,不能使用s[count]
67 if (count < len) {
68 //扫描字符串,若为数字压入数字栈,若为运算符压入不确定执行顺序的运算符栈
69 if (s[count] >= '0' && s[count] <= '9') {//字符串转数字atoi
70 int number = s[count++] - '0';
71 Push(nums, number);//函数声明里栈是指针传递
72 }
73 else {
74 //若当前扫描到的运算符优先级大于栈首运算符优先级,则压入栈中,否则弹出栈中所有>=当前字符优先级的字符
75 //若遇到),则将直到(的所有运算符依次出栈
76 if (s[count] == '(' || getTop(opech) == '(' || isEmpty(opech)) {//所有直接入栈的情况
77 Push(opech, s[count++]);
78 }
79 else if (s[count] == '+' || s[count] == '-') {//可弹出+-*/,或者什么都不谈直接入展
80 while (getTop(opech) != '(' && !isEmpty(opech)) {//排除栈空情况
81 calcu(nums, opech);
82 }
83 Push(opech, s[count++]);//栈为空
84 }
85 else if (s[count] == '*' || s[count] == '/') {
86 //禁止使用while(!= || !=)有歧义,只要为+就非-,满足条件,
87 while (getTop(opech) == '*' || getTop(opech) == '/') {//只能弹出*/,不需要判空
88 calcu(nums, opech);
89 }
90 Push(opech, s[count++]);
91 }
92 else if (s[count] == ')') {
93 while (getTop(opech) != '(') {//当栈为空时也满足不等于的条件
94 if (isEmpty(opech))break;
95 calcu(nums, opech);
96 }
97 char non;
98 Pop(opech, non);
99 count++;
100 }
101 }
102 }
103 else {//字符串扫描完,只需对还未空的运算符栈操作
104 calcu(nums, opech);
105 }
106 }
107 return nums->next->num;
108 }
109 int main() {
110 const char* s="3+(4+6)/2-2*(3+3)";
111 int len = strlen(s);
112 int result = Polish(s, len);
113 cout << "result is" << result << endl;
114 }