【C++】Qt实现简易的计算器(附代码)

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结


运行截图

请添加图片描述

中缀表达式和后缀表达式

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

中缀表达式转换为后缀表达式

  • 创建一个空栈和一个空串,用于存放运算符转换后的后缀表达式

  • 从左到右遍历中缀表达式中的每个元素:

  1. 如果当前元素是操作数,将其添加到输出串的末尾;

2.如果当前元素是左括号“(”,将其压入栈中;

3.如果当前元素是右括号“)”,则重复出栈操作直到栈顶元素是左括号,并将所有操作符加入输出串中;

4.如果当前元素是操作符,并且其优先级低于或等于栈顶运算符,则弹出栈顶元素并将其加入输出串中,然后再将当前操作符压入栈中;

5.如果当前元素是操作符,并且其优先级高于栈顶元素,则直接将当前操作符入栈

  • 当中缀表达式中所有元素被处理完毕后,将栈中剩余的所有操作符都加入输出串中。

最终得到的输出串就是中缀表达式对应的后缀表达式


根据✖乘号的优先级,补充括号

拆解表达式:

  • 左侧存放数据,右侧存放符号

  • 当遇到右括号时,将左右括号中的符号放到左侧,剩下的符号依然在右侧

  • 重复过程就得到了后缀表达式

后缀表达式计算

当遇到操作数时,将其压入栈中;当遇到运算符时,从栈中弹出相应数量的操作数进行运算,将结果再压入栈中,直到表达式结束,栈顶元素即为计算结果。


核心计算函数:

利用中缀表达式转后缀表达式再进行运算

double MainWindow::calcul(QString sourceStr)
{
    //计算

    qDebug()<<"sourceStr:"<<sourceStr<<endl;

    //存储后缀表达式
    QString str;
    //存储运算符的栈
    QStack<QChar> st;

    for(auto i : sourceStr)
    {
        //数字或小数点直接存入字符串
        if((i <= '9' && i >= '0') || i == '.'){
            str += i;
        }
        //如果是 + -
        if(i == '+'||i == '-')
        {
            //添加空格作为分隔
            str += ' ';
            //当栈不为空且栈顶运算符优先级不低于栈顶元素则入栈,否则出栈栈顶元素后入栈
            while(!st.empty() && st.top() != '+' && st.top() != '-')
            {
                //出栈栈顶元素
                str += st.pop();
                str += ' ';
            }
            //入栈
            st.push(i);
        }
        //如果是 * /
        if(i == '*'||i == '/')
        {
            str += ' ';
            //直接入栈
            st.push(i);
        }
    }
    //出栈剩余的运算符添加到后缀表达式中
    while(!st.empty())
    {
        str += ' ';
        str += st.pop();
    }

    qDebug()<<"str:"<<str<<endl;

    QStack<double> result;
    QString num;
    //遍历后缀表达式
    for(auto i : str)
    {
        if((i >= '0' && i <= '9') || i == '.' || i == ' ')
        {
            //数字或小数
            if((i >= '0' && i <= '9') || i == '.' )
            {
                num += i;
            }
            //遇到空格且数字不为空
            if(i == ' '&&!num.isEmpty())
            {
                //将数字转为浮点数入栈
                result.push(num.toDouble());
                num.clear();
            }
        }
        //加法 取出两个进行运算
        if(i == '+'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2+temp1);
        }
        //减法
        if(i == '-'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2-temp1);
        }
        //乘法
        if(i == '*'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2*temp1);
        }
        //除法
        if(i == '/'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2/temp1);
        }
    }

    qDebug()<<"res:"<<result.top()<<endl;


    return result.top();
}

主要代码

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),fuhao(true)
    , ui(new Ui::MainWindow),str("")
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton1_clicked()
{
    str+="1";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton2_clicked()
{
    str+="2";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton3_clicked()
{
    str+="3";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton4_clicked()
{
    str+="4";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton5_clicked()
{
    str+="5";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton6_clicked()
{
    str+="6";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton7_clicked()
{
    str+="7";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton8_clicked()
{
    str+="8";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButton9_clicked()
{
    str+="9";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButtonDian_clicked()
{
    if(!fuhao)
    {
        str+=".";
        ui->Display->setText(str);

        fuhao = true;
    }

}


void MainWindow::on_pushButton0_clicked()
{
    str+="0";
    ui->Display->setText(str);
    fuhao = false;
}


void MainWindow::on_pushButtonCheng_clicked()
{
    if(!fuhao)
    {
        str+="*";
        ui->Display->setText(str);

        fuhao = true;
    }
}


void MainWindow::on_pushButtonJia_clicked()
{
    if(!fuhao)
    {
        str+="+";
        ui->Display->setText(str);

        fuhao = true;
    }
}


void MainWindow::on_pushButtonJian_clicked()
{
    if(!fuhao)
    {
        str+="-";
        ui->Display->setText(str);

        fuhao = true;
    }
}


void MainWindow::on_pushButtonChu_clicked()
{
    if(!fuhao)
    {
        str+="/";
        ui->Display->setText(str);

        fuhao = true;
    }
}


void MainWindow::on_pushButtonClear_clicked()
{
    str = "";
    ui->Display->setText(str);
}


void MainWindow::on_pushButtonDel_clicked()
{
    str.remove(str.size()-1,1);
    ui->Display->setText(str);
}


void MainWindow::on_pushButtonRes_clicked()
{


    double Res = calcul(str);
    char strRes[10];
    memset(strRes,0,sizeof(strRes));
    sprintf(strRes,"%.2f",Res);
    ui->Display->setText(strRes);

    fuhao = true;
     str = "";
}

double MainWindow::calcul(QString sourceStr)
{
    //计算

    qDebug()<<"sourceStr:"<<sourceStr<<endl;

    //存储后缀表达式
    QString str;
    //存储运算符的栈
    QStack<QChar> st;

    for(auto i : sourceStr)
    {
        //数字或小数点直接存入字符串
        if((i <= '9' && i >= '0') || i == '.'){
            str += i;
        }
        //如果是 + -
        if(i == '+'||i == '-')
        {
            //添加空格作为分隔
            str += ' ';
            //当栈不为空且栈顶运算符优先级不低于栈顶元素则入栈,否则出栈栈顶元素后入栈
            while(!st.empty() && st.top() != '+' && st.top() != '-')
            {
                //出栈栈顶元素
                str += st.pop();
                str += ' ';
            }
            //入栈
            st.push(i);
        }
        //如果是 * /
        if(i == '*'||i == '/')
        {
            str += ' ';
            //直接入栈
            st.push(i);
        }
    }
    //出栈剩余的运算符添加到后缀表达式中
    while(!st.empty())
    {
        str += ' ';
        str += st.pop();
    }

    qDebug()<<"str:"<<str<<endl;

    QStack<double> result;
    QString num;
    //遍历后缀表达式
    for(auto i : str)
    {
        if((i >= '0' && i <= '9') || i == '.' || i == ' ')
        {
            //数字或小数
            if((i >= '0' && i <= '9') || i == '.' )
            {
                num += i;
            }
            //遇到空格且数字不为空
            if(i == ' '&&!num.isEmpty())
            {
                //将数字转为浮点数入栈
                result.push(num.toDouble());
                num.clear();
            }
        }
        //加法 取出两个进行运算
        if(i == '+'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2+temp1);
        }
        //减法
        if(i == '-'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2-temp1);
        }
        //乘法
        if(i == '*'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2*temp1);
        }
        //除法
        if(i == '/'){
            double temp1 = result.pop();
            double temp2 = result.pop();
            result.push(temp2/temp1);
        }
    }

    qDebug()<<"res:"<<result.top()<<endl;


    return result.top();
}

界面设计

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)
  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天喜Studio

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

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

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

打赏作者

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

抵扣说明:

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

余额充值