近期上程序设计综合实践这门课,第一项作业是实现一个计算器。
由于我只会c++语言,便简单学习了一下Qt,利用Qt的ui设计功能完成了作业,代码总计约六百行。
源码上传至Github。
值得一提的是,本以为copy一下以前写的数据结构再写一点槽函数,很快就能解决;实际发现曾经写的代码bug百出,完全跑不起来。
蚝蚝饭丝,以后写完,测试完再帖进博客。
废话讲完,下面写实现过程。
整体思路方面,建一个字符向量,用于存放所要计算的表达式,计算器的按钮向其中输入组成表达式的一个个字符。
同时定义一个string类用于输出显示,每次按下按钮就调用lineEdit的setText函数将当前表达式显示出来,强大的QString封装了大量实用的函数,大大简化了程序的实现。
设置另外四个命令按钮:C(清空),->(退格),=(计算结果并显示),RPN(转换为逆波兰表达式)。
一些细节:
建两个栈,操作符栈optr与操作数栈opnd
定义函数isDigit用于判断当前元素是数据还是运算符,定义函数readNumber读取完整数据
按下“=”以后,先调用isDigit,
if ture,则readNumber后opnd入栈
否则,判断栈顶运算符与当前运算符的优先级关系
打表便于switch1
2
3
4
5
6
7
8
9
10
11
12
13
14
15static char orderBetween[10][10]= //对优先级关系制表
{
// |-------------当前运算符----------------|
// + - * / ^ ! % ( ) \0
/*-- + */ {'>','>','<','<','<','<','<','<','>','>'},
/* | - */ {'>','>','<','<','<','<','<','<','>','>'},
/*栈 * */ {'>','>','>','>','<','<','>','<','>','>'},
/*顶 / */ {'>','>','>','>','<','<','>','<','>','>'},
/*运 ^ */ {'>','>','>','>','>','<','>','<','>','>'},
/*算 ! */ {'>','>','>','>','<','<','>',' ','>','>'},
/*符 % */ {'>','>','>','>','<','<','>','<','>','>'},
/* | ( */ {'<','<','<','<','<','<','<','<','=',' '},
/* | ) */ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
/*--\0 */ {'<','<','<','<','<','<','<','<',' ','='}
};
初始化一个数组实现字符到下标的转换1
static char allOptr[10]={'+','-','*','/','^','!','%','(',')','\0'}; //所有运算符
如果当前运算符优先级更高,则推迟计算,optr入栈
如果两者相等,则为匹配的括号或结束符,同时忽略
如果栈顶运算符优先级更高,则弹出运算符,在操作数栈中取出数据计算,计算结果入栈
循环完毕,计算结果存储在opnd栈中
至于RPN,只需将以上过程中,readNumber以及栈顶运算符优先级更高的情况接入string尾部,删除计算和入栈即可