中缀表达式求值 = 中缀转后缀 + 后缀表示式求值
1. 中缀表达式转后缀表达式
12+8-25/3-6*(5+3)
12 8 + 25 3 / - 6 5 3 + * -
中缀表达式字符串从左至右,
若遇到运算数,则直接将数字输出
若遇到运算符 ±*/ ,则与栈顶元素比较,若是该运算符优先级高于栈顶元素优先级,则入栈;若是该运算符低于或等于栈顶元素优先级,则将栈顶元素出栈并输出,继续将该运算符与栈顶元素比较,直到该运算符优先级高于栈顶元素优先级,将其入栈。
若遇到左括号,则入栈,若遇到右括号,则将左括号之前的所有元素出栈。
读到字符串尾,将所有堆栈元素依次弹出。
注:
同优先级左边的运算符优先级更高;
栈顶元素为空时,空元素优先级最低;
左括号入栈之前优先级最高,入栈之后优先级最低。
//本函数C++实现,支持的运算符仅为 + - * / ()
string midToPost(string mid) {
stack stk;
string post;
for (int i = 0; i < mid.length(); i++) {
//cout << post << endl;
if (mid[i] >= 'a'&&mid[i] <= 'z') {
post += mid[i];
}
else if (mid[i] == '+' || mid[i] == '-') {
if (stk.empty() || stk.top() == '(') {
stk.push(mid[i]);
}
else {
post += stk.top();
stk.pop();
while (!stk.empty() && stk.top() != '(') {
post += stk.top();
stk.pop();
}
stk.push(mid[i]);
}
}
else if (mid[i] == '*' || mid[i] == '/') {
if (stk.top() == '+' || stk.top() == '-' || stk.empty() || stk.top() == '(') {
stk.push(mid[i]);
}
else {
post += stk.top();
stk.pop();
while (!stk.empty() && stk.top() != '(') {
post += stk.top();
stk.pop();
}
stk.push(mid[i]);
}
}
else if (mid[i] == '(') {
stk.push(mid[i]);
}
else if (mid[i] == ')') {
while (stk.top() != '(') {
post += stk.top();
stk.pop();
}
stk.pop();
}
else {
cout << "表达式格式有误或遇到不明字符!" << endl;
}
}
while (!stk.empty()) {
post += stk.top();
stk.pop();
}
return post;
}
2. 后缀表达式求值
后缀字符串从左至右扫描:
若遇到运算数,则入栈
若遇到运算符,则取栈顶两个元素进行运算后入栈
直到后缀表达式扫描结束,栈里只剩下一个元素,即为表达式的值int getValue(string post) {
stack stk;
for (int i = 0; i < post.length(); i++) {
if (post[i] >= 'a' && post[i] <= 'z') {
stk.push(post[i]);
}
else {
int tmp = stk.top();
stk.pop();
switch(post[i]){
case '+':{
tmp += stk.top();
break;
}
case '-':{
tmp -= stk.top();
break;
}
case '*':{
tmp *= stk.top();
break;
}
case '/':{
tmp /= stk.top();
break;
}
}
stk.pop();
stk.push(tmp);
}
}
return stk.top();
}
3.后缀表达式建树
后缀字符串从左至右扫描:
若遇到运算数,则建立一个节点,值为该运算数,将节点指针入栈
若遇到运算符,则建立一个节点,值为该运算符,将栈顶两个元素出栈,分别为当前节点的左右子树,将当前节点指针入栈
直到后缀表达式扫描结束,栈里只剩下一个元素,即为表达式树的根节点struct node {
char data;
node* left;
node* right;
};
node* buildTree(string post) {
stack stk;
for (int i = 0; i < post.length(); i++) {
node* tmp = new node;
tmp->left = NULL;
tmp->right = NULL;
if (post[i] >= 'a' && post[i] <= 'z') {
tmp->data = post[i];
stk.push(tmp);
}
else {
tmp->data = post[i];
tmp->right = stk.top();
stk.pop();
tmp->left = stk.top();
stk.pop();
stk.push(tmp);
}
}
return stk.top();
}