- g一个字符串s是一个有效的四则运算表达式,请计算该表达式的值
1+2
,得到32*(2+3)
,得到10(15%(5-3)+6)*(2+3)
,得到35
字符串s至少包含一个运算符
字符串a中的操作数均为数字字面量,但可能包含小数
完成下面代码
/*
* 得到四则运算的结果
* @params {String} s四则运算表达式
* @return {Boollean}
*/
function compute(s){
// code here
}
demo
// 声明一个栈,用于存放数据
class Stack {
// 存放栈数据的数组
_datas = [];
// 放入栈一条数据
push = function (data) {
this._datas.push(data);
};
// 栈中弹出一个数据
pop = function () {
return this._datas.pop();
};
// 去除栈顶的数据
getTop = function () {
return this._datas[this._datas.length - 1];
};
}
// 声明四则运算的表达方式 (+-*/%)
const operators = {
"+": {
level: 1,
compute(num1, num2) {
return num1 + num2;
},
},
"-": {
level: 1,
compute(num1, num2) {
return num1 - num2;
},
},
"*": {
level: 2,
compute(num1, num2) {
return num1 * num2;
},
},
"/": {
level: 2,
compute(num1, num2) {
return num1 / num2;
},
},
"%": {
level: 2,
compute(num1, num2) {
return num1 % num2;
},
},
};
/**
* 声明一个扫描器
* @param {*} s 字符串
*/
function Scanner(s) {
// 剔除表达式的中的空格
this.s = s.replace(/\s/g, "");
// 判断下一个卡开头字符串是不是数字
this.numberExp = /^\d+(\.\d+)?/;
// 判断下一个字符是不是运算符
this.opExp = /^[\(\)\+\-\*\/\%]/;
}
//获取字符串的下一个字符
Scanner.prototype.next = function () {
// 如果字符串为空直接返回
if (this.s.length === 0) {
return null;
}
// 数字表达的结果
const match = this.s.match(this.numberExp);
// 保存返回结果
let result;
if (match) {
result = {
type: "number",
value: +match[0],
};
// 匹配过的字符删除
this.s = this.s.substr(match[0].length);
} else {
result = {
type: "operator",
value: this.s[0],
};
// 匹配过的字符串删除
this.s = this.s.substr(1);
}
return result;
};
// 声明一个计算函数
function compute(s) {
// 声明一个栈保存数字
const numberStack = new Stack();
// 声明一个字符栈保存操作符
const opStack = new Stack();
// 声明一个辅助计算函数
function _compute() {
// 获取符号栈栈顶操作符
const topOp = opStack.getTop();
if (!topOp) {
return false;
} else if (topOp === "(") {
opStack.pop();
return false;
} else {
opStack.pop();
const num1 = numberStack.pop();
const num2 = numberStack.pop();
const result = operators[topOp].compute(num2, num1);
numberStack.push(result);
return true;
}
}
// 声明一个处理操作符的函数
function _handeNextOpertator(op) {
let topOp = opStack.getTop(); // 得到目前栈顶的符号
if (op === ")") {
while (_compute()) {}
} else if (
!topOp ||
op === "(" ||
topOp === "(" ||
operators[op].level > operators[topOp].level
) {
// 如果栈顶是空,当前符号是(,或者栈顶是(),或者当前符号的优先级高,直接入栈
opStack.push(op);
} else {
// 如果当前的符号优先级<=栈顶符号,运算,递归运算
_compute();
_handeNextOpertator(op);
}
}
// 扫描器
const scanner = new Scanner(s);
let next;
while ((next = scanner.next())) {
if (next.type === "number") {
numberStack.push(next.value);
} else {
_handeNextOpertator(next.value);
}
}
// 符号栈清空
while (_compute());
// 返回计算结果
return numberStack.getTop();
}
const result = compute("2.5 * ( 4 + 6 ) - 2*3%5");
console.log("result", result);