QT学习项目一之计算器
计算器需求
1、UI设计
需求:九个基本数字,小数点,基本运算符号,回退,等于,一个输入和显示的lineEdit。
如图:
2、功能设计
功能设计即使,编写计算器实现的逻辑功能代码,在一个完整的应用程序中,UI界面的实现和逻辑功能实现的代码应该分开实现,UI界面通过接口(父类虚函数)调用逻辑功能中的代码,但不是直接去使用,最后通过一个类,将UI和功能实现封装起来。实现整个计算器的应用程序。
2.1:计算器逻辑功能之一——分离(spilit用队列实现)
我们计算器输入的是一串字符串,我们首先需要将字符串中数字、运算符、括号分开。
tips
我们需要注意的是正负号与运算符之间的区分:三种情况
1:+ -前面啥字符都没有即为 正负号
2:+ -前面的字符为( )即为 正负号
3:+ -前面的字符为+ -即为正负号
2.2:计算器逻辑功能之一——匹配(match用栈实现)
注意上面分离的tips即可正确分离输入的字符串,但是我们需要对分离的tips进行匹配,因为用户输入的表达式可能不规范。
匹配:即匹配左右括号是否对等,不对等就输出false。
方法:如果遇到左括号压入栈中,遇到右括号出栈。字符队列遍历结束后,判断最后栈中是否还有元素。
2.2:计算器逻辑功能之一——中缀转后缀(transform 队列 栈)
中缀表达式是我们容易看明白的表达式,但是计算机不容易识别和运算。我们需要把中缀表达式转为后缀表达式。
中缀表达式: 1+2✖3/6
后缀表达式: 123✖6/+
中缀转后缀的实现:
定义一个输入队列、输出队列、运算符号栈,如果输入队列中的是数字,就入输出队列。
如果是运算符就入栈,直到遇到的运算符的优先级<=前面入栈的运算符的优先级,就出栈,并 且入输出队列,然后将现在的运算符入栈。
tips
除了判断运算符之外,还需要判断左右括号。
是左括号就入栈,遇到右括号就出栈,入队列,直到栈顶是左括号,再将左括号出栈。
当然其中我们需要加一些细节判断,比如遇到右括号的时候,栈顶正好是左括号,那我们直接 出栈就好,不需要入队列了。
以上就是实现实现后缀转中缀的思路。
2.2:计算器逻辑功能之一——后缀计算(calculator 栈)
我们将后缀表达式队列依次遍历,定义一个结果栈,依次遍历后缀表达式队列,如果是数字就入栈,如果是运算符,就出栈两次,分别为右运算数和左运算数,将字符串转换为double类型,根据运算符计算结果,再将计算结果转为字符串,入栈。
栈中存放的最后一个字符串即为最后的结果。
3.对象接口。
根据上述的 1 2步骤我们定义好了 CalculatorUI 类 和 CalculatorDec类
但是我们UI类中并不需要用到Dec类中的全部函数,所以我们这里定义一个纯虚函数类(ICalculator类),
定义接口,再让Dec继承(ICalculator类),UI类成员只需要定义一个父类指针,指向子类,即可使用子类方法,实现接口。
4、封装
我们需要一个类将UI和Dec封装在一起,形成一个真正的计算器类。
实现示意图
至此,计算器qt项目的思路就如上所示。