四则混合计算器主要算法在于前缀表达式转后缀表达式,再通过波兰逆算法实现。具体实现步骤参考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