基于 Shunting Yard 算法 的 C++17 数学表达式求值器,支持中缀表达式转后缀表达式(逆波兰表示法)并求值。
| 功能 | 说明 |
|---|---|
| 基础运算 | +、-、*、/、%(取模)、^(幂运算) |
| 括号嵌套 | 支持任意层级 (、) |
| 一元负号 | 自动识别负数,如 -5+3、(-2)^2 |
| 数值类型 | 整数与浮点数混合运算 |
| 优先级 | ^ > * / % > + -,^ 右结合 |
| 空白处理 | 自动忽略空格 |
# 编译
g++ -std=c++17 -O2 -o ExprEval ExprEval.cpp
# 运行
./ExprEvalENTER U EXPRESSION:
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3 = 3.00012
ENTER U EXPRESSION:
-5 + 3 * 2
-5 + 3 * 2 = 1
ENTER U EXPRESSION:
2 ^ 3 ^ 2
2 ^ 3 ^ 2 = 512
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 3 | ^ |
右结合 |
| 2 | * / % |
左结合 |
| 1 | + - |
左结合 |
- 除零错误:
ERROR : 5 / 0! - 取模零错误:
ERROR : 5 % 0! - 操作数不足:
ERROR : CONT HAVE ENOUGHT NUM(S) - 表达式错误:
ERROR : U EXPRESSION IS WORNG.
ExprEval.cpp
├── op_doing() # 获取运算符优先级
├── op_is_left() # 判断左结合性
├── op_is_using() # 判断有效运算符
├── count() # 二元运算实现
├── is_minus() # 判断一元负号
├── read_other_op() # 读取数学常数 e / pi
├── read_string() # 读取数字(支持负数/浮点/常数)
├── sol_string() # 中缀转后缀(核心算法)
├── count_p() # 后缀表达式求值
├── reading_form_file() # 文件输入输出处理
├── reading_form_cin() # 键盘输入处理
└── main() # 入口:菜单选择并分发
Shunting Yard 算法(Dijkstra, 1961)
- 词法分析:遍历字符串,识别数字、运算符、括号
- 中缀转后缀:使用栈处理运算符优先级,输出逆波兰表达式
- 后缀求值:使用栈对后缀表达式进行求值
时间复杂度:O(n),空间复杂度:O(n)
- 数学常数e,pi支持
- 数学函数:
sin,cos,sqrt,log,abs - 变量定义与赋值
- 命令行参数支持:
./ExprEval "1+2*3" - 文件输入支持
- 更详细的错误定位(指出错误位置)
- 单元测试
MIT © Yunlk