如何将中缀表达式求值的JavaScript代码转换为Dart代码
Dart 实现中缀表达式计算器(支持优先级与括号)
1. 自定义栈类
Dart 无内置栈结构,先实现通用泛型栈:
class Stack<T> { final List<T> _items = []; void push(T item) => _items.add(item); T pop() => _items.removeLast(); T peek() => _items.last; bool get isEmpty => _items.isEmpty; int get length => _items.length; }
2. 核心计算逻辑
采用双栈法(操作数栈+运算符栈),处理多位数、运算符优先级与括号:
double calculateInfix(String expression) { final operands = Stack<double>(); final operators = Stack<String>(); // 运算符优先级定义 final precedence = { '+': 1, '-': 1, '*': 2, '/': 2, '(': 0, }; int i = 0; while (i < expression.length) { final char = expression[i]; // 跳过空格 if (char == ' ') { i++; continue; } // 处理多位数(支持小数) if (RegExp(r'[0-9.]').hasMatch(char)) { String numStr = ''; while (i < expression.length && RegExp(r'[0-9.]').hasMatch(expression[i])) { numStr += expression[i]; i++; } operands.push(double.parse(numStr)); continue; } // 处理左括号 if (char == '(') { operators.push(char); i++; continue; } // 处理右括号:弹出运算符直到匹配左括号 if (char == ')') { while (operators.peek() != '(') { _performOperation(operands, operators); } operators.pop(); // 移除左括号 i++; continue; } // 处理运算符:按优先级弹出栈顶运算符并计算 if (precedence.containsKey(char)) { while (!operators.isEmpty && precedence[operators.peek()]! >= precedence[char]!) { _performOperation(operands, operators); } operators.push(char); i++; continue; } throw FormatException('无效字符: $char'); } // 处理剩余运算符 while (!operators.isEmpty) { _performOperation(operands, operators); } return operands.pop(); } // 执行运算:弹出操作数与运算符,计算后压回操作数栈 void _performOperation(Stack<double> operands, Stack<String> operators) { final b = operands.pop(); final a = operands.pop(); final op = operators.pop(); switch (op) { case '+': operands.push(a + b); break; case '-': operands.push(a - b); break; case '*': operands.push(a * b); break; case '/': if (b == 0) throw StateError('除数不能为0'); operands.push(a / b); break; default: throw FormatException('无效运算符: $op'); } }
3. 使用示例
void main() { try { final result1 = calculateInfix('100 * (2 + 12) / 14'); print(result1); // 输出: 100.0 final result2 = calculateInfix('3 + 4 * 2 / (1 - 5)'); print(result2); // 输出: 1.0 } catch (e) { print(e); } }
关键说明
- 泛型栈类可复用在其他场景
- 支持多位数与小数解析
- 运算符优先级通过Map定义,可灵活扩展(如添加幂运算
^) - 括号通过"左括号入栈、右括号匹配弹出"逻辑处理
- 运算时注意操作数顺序:后弹出的是第二个操作数(如
a - b中,b后入栈先弹出)
内容的提问来源于stack exchange,提问作者Ayz
相关产品推荐
相关产品推荐

