主要功能
1.实现类似于1+2+3+(2*5)的计算
2.实现双位数的计算
1.绑定
前言
首先,必须得了解一下逆波兰式是什么
一个由中缀表达式变为后缀的方法
but:太懒了,不想写
主要的思路是:将一个表达式存入两个栈,一个栈用于存放数字,一个栈用于存放字符,字符栈主要运用于过渡,分配结束后,所有的后缀表达式都会存在与数字栈
最后利用foreach取出栈内的数字和字符,一边取出一边计算,定义一个数组,遇到数字时,入栈,取出栈中的字符时,计算表达式,最后得出的结果存于数组的第0位
一、布局并且给给每一个按钮绑定
1.绑定
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); static QChar arr[]= { '1','2','3','c', '4','5','6','*', '7','8','9','/', '0','+','-','=', '(',')' }; //存储按钮文本 int idx = 0; const QObjectList &obj = ui ->centralWidget->children(); foreach(auto var,obj) //auto var 自动定义数据类型,C++11的写法,遍历对象 { QPushButton *btn = dynamic_cast<QPushButton *>(var); if(btn) { btn->setText(arr[idx++]); //设置每一个按钮的文本 connect(btn,&QPushButton::clicked,this,&MainWindow::onPushButtonClick);//qt5版本信号连接 } } }
2.压入栈
代码如下(示例):
bool MainWindow::up(QString str) //设置出栈判断函数
{
if( (sta_opera.top()=="*")||(sta_opera.top()=='/') )
{
if( (str=="+") || (str=='-') || (str=="*") || (str=='/') )
{
return 1;
}
}
if( (sta_opera.top()=="-")||(sta_opera.top()=='+') )
{
if( (str=="+") || (str=='-'))
{
return 1;
}
}
return 0;
}
void MainWindow::onPushButtonClick()
{
QObject *obj = QObject::sender(); //sender 谁触发了信号,这个指针就指向谁
QPushButton *btn = dynamic_cast<QPushButton *>(obj);
if(btn->text()=='c') //清空显示textEdit
{
ui->textEdit->clear();
while(!sta_num.isEmpty()) //清空数字栈
{
sta_num.pop();
}
while(!sta_opera.isEmpty()) //清空字符栈
{
sta_opera.pop();
}
}
else
{
ui->textEdit->setText(ui->textEdit->toPlainText()+btn->text());
if( ('0' <= btn->text()) && (btn->text()<='9'))
{
tmp = tmp + btn->text(); //存储数字字符串
// qDebug() << tmp; //用于bug调试
}
else if(btn->text()=='=')
{
sta_num.push(tmp); //将存储的数字字符串入栈,并且清空
tmp.clear();
while(!sta_opera.isEmpty()) //剩余符号进入数字栈
{
QString opera = sta_opera.pop();
sta_num.push(opera);
}
qDebug()<<sta_num;
ui->textEdit->setText(ui->textEdit->toPlainText()+Sum()); //计算结果显示
}
else //当为符号时-----------------------------------------------
{
if( (btn->text()!='(') ) //当不是括号时,发送
{
sta_num.push(tmp); //将存储的数字字符串入栈,并且清空
tmp.clear();
}
if( sta_opera.isEmpty()==1 ) //如果是第一位直接入栈
{
sta_opera.push(btn->text());
}
else
{
if(btn->text()==')') //遇到括号全部出栈
{
while(1)
{
QString pre = sta_opera.pop();
if( pre=='(') //停止出栈
{
break;
}
sta_num.push(pre);
}
}
else if( up(btn->text())==0) //若是符号满足优先级条件
{
sta_opera.push(btn->text());
}
else if(up(btn->text())==1)//优先级出栈条件
{
QString opera = sta_opera.pop(); //(*或/)先出
sta_num.push(opera); //再入
sta_opera.push(btn->text());//(+或-)入字符栈
}
}
}
}
}
3.计算结果
代码如下(示例):
QString MainWindow::Sum()
{
int idx = 0;
foreach (auto var, sta_num) {
if( (var>='0') && (var<='9')) //比较是否为数字
{
numArr[idx++] = var.toInt(); //数字存入数组
}
else //若是遇到符号
{
if(var=='+')
{
numArr[idx-2]=numArr[idx-1]+numArr[idx-2]; //数组刚存入的两个数做运算,存入数组
idx--; //计算后去掉一位数的位置
}
else if(var=='-')
{
numArr[idx-2]=numArr[idx-2]-numArr[idx-1];
idx--;
}
else if(var=='*')
{
numArr[idx-2]=numArr[idx-2]*numArr[idx-1];
idx--;
}
else if(var=='/')
{
numArr[idx-2]=numArr[idx-2]/numArr[idx-1];
idx--;
}
}
}
return QString::number( numArr[0] ); //强转为字符串输出
}
4.结果演示
5.不足
没有实现小数功能,一位删除功能
5.完整代码
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStack>
int numArr[100] = {0};
static QChar arr[]=
{
'1','2','3','c',
'4','5','6','*',
'7','8','9','/',
'0','+','-','=',
'(',')'
};
bool MainWindow::up(QString str) //设置出栈判断函数
{
if( (sta_opera.top()=="*")||(sta_opera.top()=='/') )
{
if( (str=="+") || (str=='-') || (str=="*") || (str=='/') )
{
return 1;
}
}
if( (sta_opera.top()=="-")||(sta_opera.top()=='+') )
{
if( (str=="+") || (str=='-'))
{
return 1;
}
}
return 0;
}
QString MainWindow::Sum()
{
int idx = 0;
foreach (auto var, sta_num) {
if( (var>='0') && (var<='9'))
{
numArr[idx++] = var.toInt();
}
else
{
if(var=='+')
{
numArr[idx-2]=numArr[idx-1]+numArr[idx-2];
idx--;
}
else if(var=='-')
{
numArr[idx-2]=numArr[idx-2]-numArr[idx-1];
idx--;
}
else if(var=='*')
{
numArr[idx-2]=numArr[idx-2]*numArr[idx-1];
idx--;
}
else if(var=='/')
{
numArr[idx-2]=numArr[idx-2]/numArr[idx-1];
idx--;
}
}
}
return QString::number( numArr[0] );
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
int idx = 0;
const QObjectList &obj = ui ->centralWidget->children();
foreach(auto var,obj) //auto var 自动定义数据类型,C++11的写法
{
QPushButton *btn = dynamic_cast<QPushButton *>(var);
if(btn)
{
btn->setText(arr[idx++]);
connect(btn,&QPushButton::clicked,this,&MainWindow::onPushButtonClick);//qt5版本信号连接
}
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onPushButtonClick()
{
QObject *obj = QObject::sender(); //sender 谁触发了信号,这个指针就指向谁
QPushButton *btn = dynamic_cast<QPushButton *>(obj);
if(btn->text()=='c') //清空显示textEdit
{
ui->textEdit->clear();
while(!sta_num.isEmpty()) //清空数字栈
{
sta_num.pop();
}
while(!sta_opera.isEmpty()) //清空字符栈
{
sta_opera.pop();
}
}
else
{
ui->textEdit->setText(ui->textEdit->toPlainText()+btn->text());
if( ('0' <= btn->text()) && (btn->text()<='9'))
{
tmp = tmp + btn->text(); //存储数字字符串
// qDebug() << tmp; //用于bug调试
}
else if(btn->text()=='=')
{
sta_num.push(tmp); //将存储的数字字符串入栈,并且清空
tmp.clear();
while(!sta_opera.isEmpty()) //剩余符号进入数字栈
{
QString opera = sta_opera.pop();
sta_num.push(opera);
}
qDebug()<<sta_num;
ui->textEdit->setText(ui->textEdit->toPlainText()+Sum()); //计算结果显示
}
else //当为符号时-----------------------------------------------
{
if( (btn->text()!='(') ) //当不是括号时,发送
{
sta_num.push(tmp); //将存储的数字字符串入栈,并且清空
tmp.clear();
}
if( sta_opera.isEmpty()==1 ) //如果是第一位直接入栈
{
sta_opera.push(btn->text());
}
else
{
if(btn->text()==')') //遇到括号全部出栈
{
while(1)
{
QString pre = sta_opera.pop();
if( pre=='(') //停止出栈
{
break;
}
sta_num.push(pre);
}
}
else if( up(btn->text())==0) //若是符号满足优先级条件
{
sta_opera.push(btn->text());
}
else if(up(btn->text())==1)//优先级出栈条件
{
QString opera = sta_opera.pop(); //(*或/)先出
sta_num.push(opera); //再入
sta_opera.push(btn->text());//(+或-)入字符栈
}
}
}
}
}
//mainwindow.h
#define MAINWINDOW_H
#include <QStack>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
QString tmp = NULL; //存储数字
QStack <QString>sta_num; //数字栈
QStack <QString>sta_opera; //字符栈
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
bool up(QString str);
QString Sum();
private:
Ui::MainWindow *ui;
private slots:
void onPushButtonClick();
};
#endif // MAINWINDOW_H
除ui部分,未贴的代码块不做更改