VS2010+qt编写四则混合计算器(二)

四则混合计算器主要算法在于前缀表达式转后缀表达式,再通过波兰逆算法实现。具体实现步骤参考https://blog.csdn.net/sgbfblog/article/details/8001651
实现头文件如下:

#ifndef QTZLCJSQ_H
#define QTZLCJSQ_H

#include <QtWidgets/QMainWindow>
#include "ui_qtzlcjsq.h"
#include <stack>
#include <vector>
#include <string>
using namespace std;

class QTZLCJSQ : public QMainWindow
{
    Q_OBJECT

public:
    QTZLCJSQ(QWidget *parent = 0);
    ~QTZLCJSQ();

private:
    Ui::QTZLCJSQClass ui;
private slots:
        void slot0();
        void slot1();
        void slot2();
        void slot3();
        void slot4();
        void slot5();
        void slot6();
        void slot7();
        void slot8();
        void slot9();
        void slotplus();
        void slotsub();
        void slotmult();
        void slotdiv();
        void slotpot();
        void slotzuo();
        void slotyou();
        void slotdel();
        void slotback();
        void slotequal();
public:
    bool clearflag;
    bool operatorenable;
    QString s;
    int getpri(char);
    vector<string> m_input;//string类型容器
    void exchange(string,vector<string>&m_input);
    void ichange(string,vector<string>&m_input);

    double JS(vector<string> m_input);


};

#endif // QTZLCJSQ_H
#include "qtzlcjsq.h"

QTZLCJSQ::QTZLCJSQ(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
}

QTZLCJSQ::~QTZLCJSQ()
{

}
void QTZLCJSQ::slot1()
{
    if(clearflag)
        s = "1";
    else
        s += "1";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;

}
void  QTZLCJSQ::slot2()
{
    if(clearflag)
        s = "2";
    else
        s += "2";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot3()
{
    if(clearflag)
        s = "3";
    else
        s += "3";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot4()
{
    if(clearflag)
        s = "4";
    else
        s += "4";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}

void  QTZLCJSQ::slot5()
{
    if(clearflag)
        s = "5";
    else
        s += "5";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot6()
{
    if(clearflag)
        s = "6";
    else
        s += "6";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot7()
{
    if(clearflag)
        s = "7";
    else
        s += "7";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot8()
{
    if(clearflag)
        s = "8";
    else
        s += "8";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot9()
{
    if(clearflag)
        s = "9";
    else
        s += "9";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slot0()
{
    if(clearflag)
        s = "0";
    else
        s += "0";
    ui.lineEdit_input->setText(s);
    clearflag = false;
    operatorenable = true;
}
void  QTZLCJSQ::slotplus()
{
    if (operatorenable)
    {
        s += "+";
        ui.lineEdit_input->setText(s);
    }
    operatorenable = false;
}
void  QTZLCJSQ::slotsub()
{
    if (operatorenable)
    {
        s += "-";
        ui.lineEdit_input->setText(s);
    }
    operatorenable = false;
}
void  QTZLCJSQ::slotmult()
{
    if (operatorenable)
    {
        s += "*";
        ui.lineEdit_input->setText(s);
    }
    operatorenable = false;
}
void  QTZLCJSQ::slotdiv()
{
    if (operatorenable)
    {
        s += "/";
        ui.lineEdit_input->setText(s);
    }
    operatorenable = false;
}
void  QTZLCJSQ::slotpot()
{
    if (operatorenable)
    {
        s += ".";
        ui.lineEdit_input->setText(s);
    }
    operatorenable = false;
}
void  QTZLCJSQ::slotzuo()
{
    if (s.right(1)=="+"||s.right(1)=="-"||s.right(1)=="*"||s.right(1)=="/"||s=="")
    {
        s += "(";
        ui.lineEdit_input->setText(s);
        operatorenable = false;
    }
    else
        return;

}
void  QTZLCJSQ::slotyou()
{
    if (s.right(1)!="+"&&s.right(1)!="-"&&s.right(1)!="*"&&s.right(1)!="/"&&s!="."&&s.right(1)!="("&&s.contains("("))//QT字符串操作
    {
        s += ")";
        ui.lineEdit_input->setText(s);
        clearflag = false;
        operatorenable = true;
    }
    else
        return;
}
void  QTZLCJSQ::slotdel()
{
    if (s!="")  //编辑框不为空
    {
        s= s.left(s.size()-1);  //left表示从左侧截取字符串
        ui.lineEdit_input->setText(s);
        //if(s.endsWith("."||"+"||"-"||"*"||"*"||"/"||"("||")"))
        if(s.right(1)=="."||s.right(1)=="+"||s.right(1)=="-"||s.right(1)=="*"||s.right(1)=="/"||s.right(1)=="("||s.right(1)==")")
            operatorenable = false;
        else
            operatorenable = true;
    }
    else
        s= "";
    ui.lineEdit_input->setText(s);
    ui.lineEdit_output->setText("");
    ui.lineEdit_result->setText("");

}
void  QTZLCJSQ::slotback()
{
    ui.lineEdit_input->setText("");
    ui.lineEdit_output->setText("");
    ui.lineEdit_result->setText("");

    operatorenable = false;
    clearflag = true;
}
void QTZLCJSQ::slotequal()
{
    std::string cstr;//字符转换
    string deta = "";
    int j ;

    cstr = string((const char *)s.toLocal8Bit()); //QSting型转为string型

    exchange(cstr,m_input);
    将容器内的字符取出转换成string型
    for(j = 0;j < m_input.size();j++)
        deta += m_input[j];

    s = QString::fromStdString(deta);
    ui.lineEdit_output->setText(s);


    s = QString::number(JS(m_input),10,4); //double转Qstring,要设置精度,精度为4,10表示十进制

    ui.lineEdit_result->setText(s);


}
int QTZLCJSQ::getpri(char prt)
{
    switch(prt)
    {
        case '+':return 1;
        case '-':return 1;
        case '*':return 2;
        case '/':return 2;
        case '(':return 3;
        case ')':return 3;

        default: return 0;

    }
}
void QTZLCJSQ::exchange(string num,vector<string>&m_input)
{
    stack<char> stack1;
    string strum = ""; //数字字符串
    string strum2 ;  //运算符字符;
    int i = 0;
    int leng = num.size();
    while(i<leng)
    {

        if ((num[i]-'0'>=0)&&(num[i]-'0'<=9)||(num[i]=='.'))
        {
            strum += num[i];
            if (i == leng-1) //判断是否为最后一个数字,最后一个数字要压进栈
            {
                m_input.push_back(strum);
                strum ="";
            }
            i++;
            continue;
        }
        if ((num[i]=='('))
        {
            stack1.push(num[i]);
            i++;      
            continue;
        }
        if (num[i]==')')
        {
            m_input.push_back(strum);
            strum ="";  

            while(1)
            {       

                strum2 = stack1.top();
                m_input.push_back(strum2);
                stack1.pop();
                if (stack1.top()=='(')
                {
                    stack1.pop();
                    break;
                }
            }
            i++;      
            continue;
        }
        if ((num[i]=='+')||(num[i]=='-')||(num[i]=='*')||(num[i]=='/'))
        {
            if (num[i-1]!=')') //把运算符号前的数压栈 防止出现这种,因为是)时,已经压过一次了 +6)*
            {
                m_input.push_back(strum);
                strum = "";
            }

            if (stack1.empty())//如果栈空直接进站
            {
                stack1.push(num[i]);
                i++;
                continue;
            }
            //如果优先级高于栈内的
            if ((getpri(num[i]))>(getpri(stack1.top())&& num[i]!=')'))
            {
                stack1.push(num[i]);
                i++;      //必须continue中断循环重新开始
                continue;


            }
            //如果优先级低于栈内
            if ((getpri(num[i]))<=(getpri(stack1.top())))
            {
                while(1)
                {
                    if (stack1.top()=='(')//调试出的
                    {
                        stack1.push(num[i]);
                        break;
                    }
                    strum2 = stack1.top();
                    m_input.push_back(strum2);
                    stack1.pop();

                    if (stack1.empty())
                    {
                        stack1.push(num[i]);
                        break;
                    }
                    if ((getpri(num[i]))>getpri(stack1.top()))
                    {
                        stack1.push(num[i]);
                        break;
                    }
                    if (stack1.top()=='(')
                    {
                        stack1.push(num[i]);
                        break;
                    }
                }

            }       

        }
        i++;
        continue;

    }
    while(!stack1.empty())
    {
        strum2 = stack1.top();
        m_input.push_back(strum2);
        stack1.pop();

    }
    return ;

}

double QTZLCJSQ::JS(vector<string>m_input)
{
    double first;
    double second;
    double sum;


    stack<double> temp;
    int k = 0;

    while(k < m_input.size())
    {
        if((m_input[k]!="+")&&(m_input[k]!="-")&&(m_input[k]!="*")&&(m_input[k]!="/"))//不用单引号因为vector里面不只是单个字符串
        {
            temp.push(atof(m_input[k].c_str()));//atof将string型变成double型格式,记得加 .c_str()即就是取出string对象的字符串,实现到char *的转换,
        }

        else if(("+" == m_input[k]) || ("-" == m_input[k]) ||("*" == m_input[k]) ||("/" == m_input[k]))
        {
            int idx = 0;
            if ("+" == m_input[k])
            {
                idx = 0;
            }
            else if ("-" == m_input[k])
            {
                idx = 1;
            }
            else if ("*" == m_input[k])
            {
                idx = 2;
            }
            else if("/" == m_input[k])
            {
                idx = 3;
            }
            switch(idx)
            {
            case 0:
                first = temp.top();
                temp.pop();
                second = temp.top();
                temp.pop();
                sum = first + second;
                temp.push(sum);
                break;
            case 1:
                first = temp.top();
                temp.pop();
                second = temp.top();
                temp.pop();
                sum = second - first;
                temp.push(sum);
                break;
            case 2:
                first = temp.top();
                temp.pop();
                second = temp.top();
                temp.pop();
                sum = first * second;
                temp.push(sum);
                break;
            case 3:
                first = temp.top();
                temp.pop();
                second = temp.top();
                temp.pop();
                sum = second / first;
                temp.push(sum);
                break;
            }
        }
        k++;
    }
    return temp.top();
}

其中exchange函数中缀表达式转化为后缀表达式,JS则实现波逆算法
QString与string的转换可以用

std::string cstr;//字符转换
QString s;
cstr = string((const char *)s.toLocal8Bit()); //QSting型转为string型
s = QString::fromStdString(cstr);//sting型转为Qstring型


stack<double> temp;//一个double类型的栈
vector<string> m_input; //一个字符串型的容器
temp.push(atof(m_input[k].c_str()));//atof将string型变成double型格式, .c_str()即就是取出string对象的字符串,实现到char *的转换,

同时还要注意break continues 和return的用法区别
完整代码链接https://download.csdn.net/download/weixin_42355349/10616179

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值