Programming Coursework
双目运算
表达式运算
选做:
- 考虑括号
- 考虑取余运算、求平方运算
- 图形界面
- 自拟扩展功能
- 十六进制输入 input
- 小数点 .
- 四则运算 + - * /
- 计算 =
- 清空 AC
- 退格 DEL
- 取模 %
- 平方 ^2
- 幂运算 ^n
- 阶乘 !
- 左移位 <<
- 右移位 >>
- 按位与 &
- 按位或 |
- 按位异或 ^
- 按位取反 ~
- or anything else?
enum class TokType {
Number, // 数据
Op, // 单目运算符
UnaryPreOp, // 前缀运算符
UnaryPostOp,// 后缀运算符
LParen, // 左括号
RParen // 右括号
};
struct Token { // tokenization
TokType type;
QString text;
};Tokenization → Convert to RPN → Evaluate
isHex lambda 判断是否为十六进制字符 (0-9, A-F)
逐字扫
- 空格 → 跳过
- ( 或 ) → 生成括号 Token
- +, -, *, / → 生成运算符 Token
- 十六进制字符或 . → 收集完整数字,支持小数点
度场算法 (Shunting Yard) 将中缀表达式转换为逆波兰表达式(后缀表达式)
Dijkstra 调度场算法:
- 数字 → 直接输出到结果队列
- 运算符 → 比较优先级,将栈顶高优先级/同优先级运算符弹出到结果,再入栈
- 左括号 → 入栈
- 右括号 → 弹出运算符直到遇到左括号
- 最后将栈中剩余运算符弹出
evalRpn() - 逆波兰表达式求值
使用栈存储操作数
- 遇到数字 → 解析为 long double 入栈
- 遇到运算符 → 弹出两个操作数,计算结果入栈
- 最终栈中剩余一个值即为结果
处理正负号, 按 . 分割为整数部分和小数部分
整数部分:intPart = intPart * 16 + digit
小数部分:fracPart += digit / base,base 依次为 16, 256, 4096...
处理特殊值 (NaN, Inf) 分离整数和小数部分 整数部分:用 Qt 的 QString::number(intPart, 16) 直接转换 小数部分:循环乘 16 取整数位,最多 12 位 去除末尾的零