数据结构之栈的应用-后缀表达式
形式
中缀表达式:6 + (5 - 3) * 2 + 8 / 4
后缀表达式:6 5 3 - 2 * + 8 4 / +
特点:运算符位于操作数的后面
转换规则
遍历中缀表达式字符串:
- 当前字符为数字,保存到后缀表达式字符串中
- 当前字符为‘ ( ’,入栈
- 当前字符‘ ) ’,弹出栈中‘ ( ’前的所有运算符(包括‘ ( ’)
- 当前字符为普通运算符,依次弹出栈中优先级大于等于当前运算符的运算符,保存到后缀表达式字符串中,将当前运算符入栈
图示
- 6存入resultStr,‘+’号入栈
- ‘(’入栈,5resultStr,‘-’入栈,3入resultStr,遇到‘)’,‘-’出栈入resultStr,‘(’出栈,‘*’入栈(栈中没有比它优先级高的),2入resultStr
- ‘+’号入栈,‘*’,‘+’出栈入resultStr,8入resultStr,‘/’入栈,4入resultStr
- 全部出栈
实现
postfix.h
//
// Created by YuanPeng on 2018/5/30.
//
#ifndef SQSTACK_POSTFIX_H
#define SQSTACK_POSTFIX_H
#include "../liststack/liststack.h"
char *postFix(char *str);
#endif //SQSTACK_POSTFIX_H
postfix.cpp
//
// Created by YuanPeng on 2018/5/29.
//
#include "postfix.h"
#include <iostream>
using namespace std;
char *postFix(char *str) {
// 创建一个stack
Node tempStack = (Node)malloc(sizeof(Node));
tempStack->next = nullptr;
// 遍历str
int i = 0, j = 0;
static char resultStr[100]; // 后缀表达式结果字符数组
while(str[i] != '\0') {
if(str[i] >= '0' && str[i] <= '9') { // 数字就保存到字符串中
resultStr[j++] = str[i];
} else if (str[i] == '(') { // 左括号 入栈
push(tempStack, str[i]);
} else if (str[i] == ')') { // 把左括号之前的全部出栈
while (isEmpty(tempStack) == false) {
char temp1 = ' ';
getTop(tempStack, temp1);
if (temp1 == '(') { // 如果栈顶元素==‘(’则pop后退出循环
pop(tempStack, temp1);
break;
} else {
pop(tempStack, resultStr[j++]);
}
}
} else if (str[i] == '+' || str[i] == '-') { // + - 号优先度最低 所以所有运算符都要出栈
while (isEmpty(tempStack) == false) {
char temp2 = ' ';
getTop(tempStack, temp2);
if (temp2 == '+' || temp2 == '-' || temp2 == '*' || temp2 == '/') {
pop(tempStack, resultStr[j++]);
} else { // 如果遇到括号则退出循环
break;
}
}
push(tempStack, str[i]);
} else if (str[i] == '*' || str[i] == '/') { // * / 号对应的只有 * /号出栈
while (isEmpty(tempStack) == false) {
char temp3 = ' ';
getTop(tempStack, temp3);
if (temp3 == '*' || temp3 == '/') {
pop(tempStack, resultStr[j++]);
} else {
break;
}
}
push(tempStack, str[i]);
}
i++;
}
while (isEmpty(tempStack) == false) { // 最后把栈中的元素全部出栈
pop(tempStack, resultStr[j++]);
}
return resultStr;
}
后缀表达式的计算
规则:将操作数入栈,遇到运算符时取栈顶和栈顶->next进行该运算符的运算,将结果入栈。
实现:
#include <stack>
using namespace std;
int computePost(char *str) {
// 创建一个stack 这地方只需要一个int型的stack就行了 但是上面的方法用的是char类型的 所以引用stack
stack<int> tempStack;
// 遍历str
int i = 0;
int resultNum = 0;
while (str[i] != '\0') {
if (str[i] >= '0' && str[i] <= '9') { // 操作数
tempStack.push(str[i]-'0');
} else if (str[i] == '+'){
tempStack.push(compute(tempStack, str[i]));
} else if (str[i] == '-') {
tempStack.push(compute(tempStack, str[i]));
} else if (str[i] == '*') {
tempStack.push(compute(tempStack, str[i]));
} else if (str[i] == '/') {
tempStack.push(compute(tempStack, str[i]));
}
i ++;
}
resultNum = tempStack.top();
return resultNum;
}
int compute(stack<int> &s, char operCh) {
int operator1 = 0, operator2 = 0;
int result;
operator1 = s.top();
s.pop();
operator2 = s.top();
s.pop();
switch (operCh) {
case '+': result = operator2 + operator1; break;
case '-': result = operator2 - operator1; break;
case '*': result = operator2 * operator1; break;
case '/': result = operator2 / operator1; break;
}
return result;
}
ps:可能是目前最为用心的一篇博客了…