stack.js
class Stack {
constructor(){
// dataStore 保存所有数据
this.dataStore=[];
// top 指示可以添加数据的“位置”
this.top=0;
}
// 当然定义栈自己的push 方法,并让顶指针加一
push(elem){
this.dataStore[this.top++]=elem;
}
// 返回最顶部的值
peek(){
return this.dataStore[this.top-1]
}
// 出栈一个元素,即最顶部的值。并让指针减一,注意是先用后减
pop(){
return this.dataStore[--this.top]
}
// 因为无论添加值、访问值、还是出栈值,都是根据this.top
// 就像数组清空,直接令length=0
clear(){
this.top=0
}
length(){
return this.top;
}
}
中缀转后缀
const Stack = require('./stack.js')
/**
* 传入一个字符串类型的计算式
* @param {*} op
*/
function converted(op) {
// 符号先入栈s1;数字直接入栈s2
const s1 = new Stack();
const s2 = new Stack();
let nums = ''; // 方便入栈完整数字
for (let i = 0; i < op.length; i++) {
switch (op[i]) {
// 实现圆括号。方括号、大括号类似
case '(': s1.push(op[i]); break;
// 遇到后括号,将s1栈顶至前括号"("之间的所有运算符依次入栈 s2,然后扔掉"("
case ')':
while (s1.peek() != '(') {
s2.push(s1.pop())
}
s1.pop();
break;
case '+':
case '-':
while (s1.top != 0 && s1.peek()!='(') {
s2.push(s1.pop())
}
s1.push(op[i])
break;
case '*':
case '/':
s1.push(op[i]);
break;
default:
// 入栈完整数字
while ('0' <= op[i] && op[i] <= '9' || str[i] == '.') {
nums += op[i];
i++;
}
s2.push(nums);
i -= 1;
nums = '';
}
}
// 最后将s1栈中剩下的所有运算符都入栈s2
while (s1.length() > 0) {
s2.push(s1.pop())
}
return s2;
}
let s1=converted(op)
/**
* 注意,s2 栈中从底至顶排列就是中缀转后缀的表达式
* 在s2倒序,才能够用逆波兰的方式计算
* @param {*} s
*/
function reverse(s){
const s1=new Stack();
while(s.length()>0){
s1.push(s.pop())
}
return s1;
}
let s2=reverse(s1);
function operator(s2){
const s1=new Stack();
while(s2.length()>0){
let temp=s2.pop();
// 在s2中每次弹出一个元素,判断该元素的类型
// 注意,每一个元素都是字符串类型,因此用isNaN 方法判断
if(isNaN(temp)){
const t1=Number(s1.pop())
const t2=Number(s1.pop())
switch(temp){
case '+':s1.push(t2+t1);break;
case '-':s1.push(t2-t1);break;
case '*':s1.push(t2*t1);break;
case '/':s1.push(t2/t1);break;
default :return ;
}
}else {
s1.push(temp)
}
}
// s1 栈的最后一个值即为计算式结果
return s1.pop();
}
来源:CSDN
作者:qq_45209973
链接:https://blog.csdn.net/qq_45209973/article/details/104771776