头文件 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QStack>
#include <QVector>
#include <QMainWindow>
#include <QQueue>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void ToPostfix(); //中缀转后缀函数
int precedence(const QChar &oper);//优先级函数
void calculate(); //计算函数
void symbClicked();
bool pointJudge; //小数点判断
int count; //括号判断
QVector<QString> history;
QStack<QChar> signStack; //创建符号栈
QVector<QChar> postfix_expression; //创建数组变量用于后缀表达式
//QQueue<QString> postfix_expression;
private slots:
void on_btn1_clicked();
void on_btn0_clicked();
void on_btn2_clicked();
void on_btn3_clicked();
void on_btn4_clicked();
void on_btn5_clicked();
void on_btn6_clicked();
void on_btn7_clicked();
void on_btn8_clicked();
void on_btn9_clicked();
void on_btn_add_clicked();
void on_btn_div_clicked();
void on_btn_mul_clicked();
void on_btn_sub_clicked();
void on_btn_left_clicked();
void on_btn_back_clicked();
void on_btn_right_clicked();
void on_btn_equal_clicked();
void on_btn_clear_clicked();
void on_btn_point_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
源文件 main.cpp
#include "mainwindow.h"
#include <QString>
#include <QApplication> //包含一个应用程序类的头文件
//main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
//a应用程序对象,在QT中,应用程序对象,有且仅有一个
QApplication a(argc, argv);
//窗口对象 MainWindow父类->QMainWindow
MainWindow w;
//窗口对象 默认不会显示,必须要调用show方法显示窗口
w.show();
return a.exec();//让应用程序对象进入消息循环,相当代码堵塞在此行
}
源文件 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStack>
#include <QVector>
#include <QDebug>
#include <QQueue>
//命名规范
//类名 首字母大写, 单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800, 1080);
signStack.clear();
postfix_expression.clear();
pointJudge = false;//判断是否可以输入小数点
count = 0;//判断左右括号是否对称
}
//优先级次序函数
int MainWindow::precedence(const QChar &oper)
{
if(oper.cell()=='('){
return 0;
}
else if(oper.cell()=='+'||oper.cell()=='-'){
return 1;
}
else if(oper.cell()=='*'||oper.cell()=='/'){
return 2;
}
return 0;
}
//中缀转后缀函数
void MainWindow::ToPostfix()
{
QString exp = ui->output->text();
for(int i=0;i<exp.size();i++)
{
if(exp[i].isNumber()||exp[i]=='.')
{
postfix_expression.push_back(exp[i]);
}
else if(exp[i]=='(')
{
signStack.push(exp[i]);
}
else if(exp[i]==')')
{
postfix_expression.push_back(' '); //空格用于分隔数字,使其不被认为是一整个数字
while(signStack.top()!='(')
{
postfix_expression.push_back(signStack.pop());
}
signStack.pop();
}
else if(!signStack.empty())
{
postfix_expression.push_back(' ');
if (precedence(exp[i])>precedence(signStack.top()))
{
signStack.push(exp[i]);
}
else
{
//qDebug()<<postfix_expression; //输出表达式
postfix_expression.push_back(signStack.pop());
signStack.push(exp[i]);
}
}
else {
postfix_expression.push_back(' ');
signStack.push(exp[i]);
}
}
while(!signStack.empty())
{
QChar c = signStack.pop();
postfix_expression.push_back(' ');
postfix_expression.push_back(c);
}
}
//实现后缀表达式计算
void MainWindow::calculate()
{
QString extra; //创建一个临时字符数组,用于转换
QStack<double> ans; //创建栈用于运算和储存结果
for(int i=0;i<postfix_expression.size();i++)
{
if(postfix_expression[i].isNumber()||postfix_expression[i]=='.')
{
extra.push_back(postfix_expression[i]);
}
else if(postfix_expression[i]==' ')
{
if(!extra.isEmpty())
{
ans.push(extra.toDouble()); //toDouble()函数 将字符型转化为浮点型数据 并入栈
extra.clear(); //转化完了后清空
}
}
else
{
double a,b;
a=ans.pop();
b=ans.pop();
if(postfix_expression[i].cell()=='+'){
ans.push(b+a);
}
else if (postfix_expression[i].cell()=='-'){
ans.push(b-a);
}
else if (postfix_expression[i].cell()=='*'){
ans.push(b*a);
}
else if (postfix_expression[i].cell()=='/'){
if(a!=0) ans.push(b/a);
else
{
ui->outans->setText("除数不能为零!");
return;
}
}
}
}
//计算器屏幕显示结果
ui->outans->setText(QString::number(ans.top()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::symbClicked()
{
QString symbol = ((QPushButton*)sender())->text();
QString exp = ui->output->text();
if(exp.right(1) == "+" || exp.right(1) == "-" || exp.right(1) == "*" || exp.right(1) == "/")
exp = exp.left(exp.size() - 1);
else if (exp == "" || exp.right(1) == "("||exp.right(1) == ".")
exp = exp + "0";
ui->output->setText(exp.append(symbol));
pointJudge = false;
}
void MainWindow::on_btn0_clicked()
{
QString s = ui->output->text();
if(s=="0") {
s = s.left(s.size() - 1);
}
ui->output->setText(s.append("0"));
}
void MainWindow::on_btn1_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("1"));
}
void MainWindow::on_btn2_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("2"));
}
void MainWindow::on_btn3_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("3"));
}
void MainWindow::on_btn4_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("4"));
}
void MainWindow::on_btn5_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("5"));
}
void MainWindow::on_btn6_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("6"));
}
void MainWindow::on_btn7_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("7"));
}
void MainWindow::on_btn8_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("8"));
}
void MainWindow::on_btn9_clicked()
{
QString s = ui->output->text();
ui->output->setText(s.append("9"));
}
void MainWindow::on_btn_add_clicked()
{
symbClicked();
}
void MainWindow::on_btn_div_clicked()
{
symbClicked();
}
void MainWindow::on_btn_mul_clicked()
{
symbClicked();
}
void MainWindow::on_btn_sub_clicked()
{
symbClicked();
}
void MainWindow::on_btn_left_clicked()
{
QString s = ui->output->text();
if(s.right(1)==".")
{
s=s.left(s.size() - 1);
pointJudge = false;
}
if(s.right(1)>="0" && s.right(1)<="9")
{
ui->output->setText(s.append("*"));
}
if (s.right(1)==')')
{
ui->output->setText(s.append("*"));
}
ui->output->setText(s.append("("));
count++;
}
void MainWindow::on_btn_back_clicked()
{
QString s = ui->output->text();
if (s.right(1)==".") pointJudge = false;
ui->output->setText(s.left(s.size() - 1));
}
void MainWindow::on_btn_right_clicked()
{
QString s = ui->output->text();
if (count>0)
{
ui->output->setText(s.append(")"));
count--;
}
}
void MainWindow::on_btn_equal_clicked()
{
if (count!=0) ui->outans->setText("左右括号不匹配!");
else
{
ToPostfix();
calculate();
QString s = ui->output->text();
QString r= ui->outans->text();
history.push_back(s);
ui->out_history->append(s);
}
}
void MainWindow::on_btn_clear_clicked()
{
ui->output->clear();
pointJudge = false;
ui->outans->clear();
}
void MainWindow::on_btn_point_clicked()
{
if (!pointJudge) {
QString s = ui->output->text();
if (s == "" ) s = s + "0";
ui->output->setText(s.append("."));
pointJudge = true;
}
}