先实现堆栈数据结构
AutoHotkey版本
;Stack
Class Stack
{
stack := []
;压栈
push(value) {
this.stack.push(value)
}
;出栈,栈为空时返回 undefined
pop() {
if (this.empty())
return "undefined1"
return this.stack.pop()
}
size() {
return this.stack.length()
}
empty() {
return this.size() == 0
}
peek() {
if (this.empty())
return "undefined2"
;~ throw Exception("栈中元素已经被取完,无法再取。")
return this.stack[this.size()]
}
}
C++版本
class Stack {
constructor() {
// 使用 Array 保存栈数据
this.stack = [];
}
// 压栈
push(value) {
this.stack.push(value);
}
// 出栈,栈为空时返回 undefined
pop() {
return this.stack.pop();
}
size() {
return this.stack.length;
}
empty() {
return this.size() === 0;
}
}
堆栈的应用,后缀表达式求值(逆波兰表达式求值)
再讲一下后缀表达式求值
后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6 5 2 3 + 8 * + 3 + *,则其求值过程如下:
1)遍历表达式,遇到的数字首先放入栈中,此时栈如下所示:
2)接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。
3)读到8,将其直接放入栈中。
4)读到“”,弹出8和5,执行85,并将结果40压入栈中。而后过程类似,读到“+”,将40和5弹出,将40+5的结果45压入栈…以此类推。最后求的值288。
AutoHotkey版本
stack:=new Stack()
evalReversePolish:="1 2 3 * + 4 5 * 6 + 7 * +" ; " 1 + 2 * 3 + (4 * 5 + 6) * 7= 189
Haystack:=evalReversePolish
NeedleRegEx:="O)(\d+|\+|\-|\*|\/|\(|\))"
Match := {Len: {0: 0}}, FoundPos := 1
While (FoundPos := RegExMatch(Haystack, NeedleRegEx, Match, FoundPos + Match.Len[0]))
{
expression:=Match.Value(0)
if(InStr("+-*/",expression))
{
val1 := stack.pop()
val2 := stack.pop()
Switch expression
{
case "+":
stack.push(val1 + val2)
case "-":
stack.push(val2 - val1)
case "*":
stack.push(val1 * val2)
case "/":
stack.push(val2 / val1)
}
}else{
;操作值直接压入栈中
stack.push(expression)
}
}
msgbox % stack.pop()
return
C++版本
const evalReversePolish = (suffixExpression) => {
const operators = ['+', '-', '*', '/'];
let stack = new Stack();
// 切割表达式,模拟读取
suffixExpression.replace(/([\d+|\+|\-|\*|\/])/g, (_, expression) => {
if (operators.includes(expression)) {
const val1 = stack.pop(),
val2 = stack.pop();
switch (expression) {
case '+':
stack.push(val1 + val2);
break;
case '-':
stack.push(val2 - val1);
break;
case '*':
stack.push(val1 * val2);
break;
case '/':
stack.push(val2 / val1);
break
}
} else {
// 操作值直接压入栈中
stack.push(parseInt(expression));
}
});
return stack.pop();
};
console.log(
evalReversePolish(
convertToReversePolish('1 + 1 * 2'))); // => 3
console.log(
evalReversePolish(
convertToReversePolish('(1 + 1) * 2'))); // => 4
console.log(
evalReversePolish(
convertToReversePolish('1 + 2 * 3 + (4 * 5 + 6) * 7'))); // => 189