js实现一个函数,对一个只包含数字,减号加号和括号的字符串表达式求值,不能使用eval
时间: 2024-04-15 17:32:05 浏览: 154
可以使用栈来实现对表达式求值,具体步骤如下:
1. 创建两个栈,一个用于存储操作数 `operandStack`,一个用于存储运算符 `operatorStack`。
2. 遍历字符串表达式,逐个字符进行处理。
3. 如果遇到数字字符,继续往后遍历,将连续的数字字符组成完整操作数,并将其转换为数字,然后将操作数压入操作数栈 `operandStack`。
4. 如果遇到运算符字符,判断当前运算符与运算符栈顶元素的优先级。如果当前运算符优先级较高或与栈顶元素相等并且栈顶元素不是左括号,则将当前运算符压入运算符栈 `operatorStack`。
5. 如果遇到左括号字符,则直接将其压入运算符栈 `operatorStack`。
6. 如果遇到右括号字符,则从运算符栈 `operatorStack` 弹出运算符进行计算,直到遇到左括号为止。每次弹出运算符时,同时从操作数栈 `operandStack` 弹出两个操作数,进行计算并将结果压入操作数栈 `operandStack`。
7. 遍历完整个表达式后,如果运算符栈 `operatorStack` 不为空,则依次弹出运算符进行计算,同时从操作数栈 `operandStack` 弹出两个操作数,将结果压入操作数栈 `operandStack`。
8. 最后,操作数栈 `operandStack` 中的唯一元素即为表达式的求值结果。
下面是实现上述逻辑的 JavaScript 函数:
```javascript
function evaluateExpression(expression) {
const operandStack = []; // 操作数栈
const operatorStack = []; // 运算符栈
// 定义运算符优先级
const precedence = {
'+': 1,
'-': 1,
'(': 0
};
// 计算结果函数
function calculate() {
const operator = operatorStack.pop();
const operand2 = operandStack.pop();
const operand1 = operandStack.pop();
switch (operator) {
case '+':
operandStack.push(operand1 + operand2);
break;
case '-':
operandStack.push(operand1 - operand2);
break;
}
}
// 遍历表达式
for (let i = 0; i < expression.length; i++) {
const char = expression[i];
if (/\d/.test(char)) { // 数字字符
let numStr = char;
// 继续往后遍历,将连续的数字字符组成完整的操作数
while (/\d/.test(expression[i + 1])) {
numStr += expression[i + 1];
i++;
}
operandStack.push(Number(numStr));
} else if (char === '+' || char === '-') { // 运算符字符
while (
operatorStack.length > 0 &&
precedence[char] <= precedence[operatorStack[operatorStack.length - 1]]
) {
calculate();
}
operatorStack.push(char);
} else if (char === '(') { // 左括号字符
operatorStack.push(char);
} else if (char === ')') { // 右括号字符
while (operatorStack[operatorStack.length - 1] !== '(') {
calculate();
}
operatorStack.pop(); // 弹出左括号
}
}
while (operatorStack.length > 0) { // 处理剩余运算符
calculate();
}
return operandStack[0];
}
```
使用示例:
```javascript
console.log(evaluateExpression("2+3*(4-1)")); // 输出 11
console.log(evaluateExpression("5+(6-2)*8")); // 输出 37
console.log(evaluateExpression("(1+2)*(3-4)+5")); // 输出 2
```
注意:以上实现仅适用于只包含数字、减号、加号和括号的简单表达式,对于更复杂的表达式或其他运算符,需要进行相应的扩展和修改。
阅读全文