基于qt的逆波兰式简易计算器

主要功能

1.实现类似于1+2+3+(2*5)的计算

2.实现双位数的计算

文章目录

前言

一、布局并且给给每一个按钮绑定

1.绑定

2.压入栈

3.计算结果

        4.结果演示

        5.不足

        5.完整代码



前言

首先,必须得了解一下逆波兰式是什么

一个由中缀表达式变为后缀的方法

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部分,未贴的代码块不做更改

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偷懒的树獭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值