头文件
history.h
#ifndef DIALOG_HISTORY_H
#define DIALOG_HISTORY_H
#include <QDialog>
#include <string>
using namespace std;
namespace Ui {
class Dialog_history;
}
class Dialog_history : public QDialog
{
Q_OBJECT
public:
explicit Dialog_history(QWidget *parent = nullptr);
~Dialog_history();
void setext(QString str);
private:
Ui::Dialog_history *ui;
};
#endif // DIALOG_HISTORY_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMessageBox>
#include "dialog_history.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_button_num9_clicked();
void on_button_num0_clicked();
void on_button_dot_clicked();
void on_button_chu_clicked();
void on_button_out_clicked();
void on_button_quyu_clicked();
void on_button_num2_clicked();
void on_button_num1_clicked();
void on_button_num3_clicked();
void on_button_num4_clicked();
void on_button_num5_clicked();
void on_button_num6_clicked();
void on_button_num7_clicked();
void on_button_num8_clicked();
void on_button_cheng_clicked();
void on_button_jian_clicked();
void on_button_jia_clicked();
void on_button_clear_clicked();
void on_button_delete_clicked();
void on_button_leftk_clicked();
void on_button_rightk_clicked();
void on_button_qiugen_clicked();
void on_button_history_clicked();
private:
Ui::Widget *ui;
Dialog_history h;
};
#endif // WIDGET_H
源文件
cal.cpp
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;
//优先级
int operate(char ch){
if(ch=='(') return 0;
else if(ch=='+'||ch=='-') return 1;
else if(ch=='*'||ch=='/'||ch=='%') return 2;
else return 4;
}
//计算
void calculate(char temp,stack<double>&Num){
double a=Num.top();Num.pop();
double innum;
double b=Num.top();Num.pop();
if(temp=='+')innum=b+a;
else if(temp=='-')innum=b-a;
else if(temp=='*')innum=b*a;
else if(temp=='/')innum=b/a;
Num.push(innum);
}
//中缀转后缀,双栈法
double twoStack(string str){
stack<double> Num;//存数字
stack<char> Ch;//存操作符
int i = 0, j;
int size = str.size();
string num;
char temp;
while (i < size) {
if (str[i] >= '0' && str[i] <= '9') {
j = i;
while ((j < size && str[j] >= '0' && str[j] <= '9') || str[j]=='.') { j++; }
//从下标i开始截取长度为j-i的字符
num = str.substr(i, j - i);
//atof函数将字符串转换成浮点型数
Num.push(atof(num.c_str()));
i = j;
}
else if(str[i]=='('||str[i]==')'){
if (str[i]=='(') Ch.push(str[i]);
else{
while(Ch.top()!='('){
temp=Ch.top();
Ch.pop();
calculate(temp, Num);
}
Ch.pop();//左括号出栈!!
}
i++;
}
else{
if (Ch.empty()) {
Ch.push(str[i]);
}
else {
while (!Ch.empty()) {
temp = Ch.top();
if (operate(temp) >= operate(str[i])) {
Ch.pop();
calculate(temp, Num);
}
else break;
}
Ch.push(str[i]);
}
i++;
}
}
while(!Ch.empty()){
temp=Ch.top();
Ch.pop();
calculate(temp,Num);
}
return Num.top();
}
history.cpp
#include "dialog_history.h"
#include "ui_dialog_history.h"
Dialog_history::Dialog_history(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_history)
{
ui->setupUi(this);
}
Dialog_history::~Dialog_history()
{
delete ui;
}
void Dialog_history::setext(QString str)
{
ui->label->setText(str);
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "calculate.cpp"
#include<QString>
int isright(string str);
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setFixedSize(this->size());
}
Widget::~Widget()
{
delete ui;
}
//存储计算式(显示和实际隔离)
string str;
string his_str;
//数字键
void Widget::on_button_num0_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"0");
str.push_back('0');
}
void Widget::on_button_num1_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"1");
str.push_back('1');
}
void Widget::on_button_num2_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"2");
str.push_back('2');
}
void Widget::on_button_num3_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"3");
str.push_back('3');
}
void Widget::on_button_num4_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"4");
str.push_back('4');
}
void Widget::on_button_num5_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"5");
str.push_back('5');
}
void Widget::on_button_num6_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"6");
str.push_back('6');
}
void Widget::on_button_num7_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"7");
str.push_back('7');
}
void Widget::on_button_num8_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"8");
str.push_back('8');
}
void Widget::on_button_num9_clicked()
{
ui->lineEdit->setText(ui->lineEdit->text()+"9");
str.push_back('9');
}
void Widget::on_button_dot_clicked()
{
if(str.back()>='0'&&str.back()<='9')//运算符前面不能没有数、点前面只能是数
{
ui->lineEdit->setText(ui->lineEdit->text()+".");
str.push_back('.');
}
}
//加减乘除取余平方
void Widget::on_button_chu_clicked()
{
//按下加减乘除后想切换另一个运算符,直接再次点击就可以切换
/*如果文本上一个字符是空格-*+/,那么按下按钮时会将最后一个字符删除,并在文本末尾添加一个符号同时修改相应数据结构*/
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%')
{
ui->lineEdit->backspace();
ui->lineEdit->setText(ui->lineEdit->text()+"÷");
str.pop_back();
str.push_back('/');
return;
}
if((str.back()>='0'&&str.back()<='9')||str.back()==')')
{//运算符前只能是数字或)
ui->lineEdit->setText(ui->lineEdit->text()+"÷");
str.push_back('/');
}
}
void Widget::on_button_cheng_clicked()
{
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%'||str.back()=='^')
{
ui->lineEdit->backspace();
ui->lineEdit->setText(ui->lineEdit->text()+"×");
str.pop_back();
str.push_back('*');
return;
}
if((str.back()>='0'&&str.back()<='9')||str.back()==')')
{//运算符前只能是数字或)
ui->lineEdit->setText(ui->lineEdit->text()+"×");
str.push_back('*');
}
}
void Widget::on_button_jian_clicked()
{
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%'||str.back()=='^')
{
ui->lineEdit->backspace();
ui->lineEdit->setText(ui->lineEdit->text()+"-");
str.pop_back();
str.push_back('-');
return;
}
if((str.back()>='0'&&str.back()<='9')||str.back()==')')
{//运算符前只能是数字或)
ui->lineEdit->setText(ui->lineEdit->text()+"-");
str.push_back('-');
}
}
void Widget::on_button_jia_clicked()
{
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%'||str.back()=='^')
{
ui->lineEdit->backspace();
ui->lineEdit->setText(ui->lineEdit->text()+"+");
str.pop_back();
str.push_back('+');
return;
}
if((str.back()>='0'&&str.back()<='9')||str.back()==')')
{//运算符前只能是数字或)
ui->lineEdit->setText(ui->lineEdit->text()+"+");
str.push_back('+');
}
}
void Widget::on_button_quyu_clicked()
{
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%'||str.back()=='^')
{
ui->lineEdit->backspace();
ui->lineEdit->setText(ui->lineEdit->text()+"%");
str.pop_back();
str.push_back('%');
return;
}
if((str.back()>='0'&&str.back()<='9')||str.back()==')')
{//运算符前只能是数字或)
ui->lineEdit->setText(ui->lineEdit->text()+"%");
str.push_back('%');
}
}
void Widget::on_button_clear_clicked()
{
ui->label_out->setText("结果");
ui->lineEdit->clear();
str.clear();
}
void Widget::on_button_delete_clicked()
{
if(!str.empty())
{//退格时前面不能没有数
ui->lineEdit->backspace();
str.pop_back();
}
}
void Widget::on_button_leftk_clicked()
{
if((str.back()>='0'&&str.back()<='9')||str.back()==')')return;
ui->lineEdit->setText(ui->lineEdit->text()+"(");
str.push_back('(');
}
void Widget::on_button_rightk_clicked()
{
if(!str.empty()&&str.back()!='(')
{//运算符前面不能没有数
ui->lineEdit->setText(ui->lineEdit->text()+")");
str.push_back(')');
}
}
void Widget::on_button_qiugen_clicked()
{
if(str.back()=='q'||str.back()==')'||str.back()=='^')return;
ui->lineEdit->setText(ui->lineEdit->text()+"√");
str.push_back('q');
}
//等于号键
void Widget::on_button_out_clicked()
{
if(isright(str)==1){
return;
}
//*****************关键函数,计算结果
double result=twoStack(str);
//保存历史数据
QString qstr=ui->lineEdit->text();
//计算过后清除缓存数据
ui->lineEdit->setText("");
ui->label_out->setText(QString::number(result));
his_str.append(qstr.toStdString()+"="+to_string(result)+'\n');
//计算式清空
str.clear();
}
//矫正
int isright(string str)
{
if(str.length()==0)return 1;
if(str.back()=='+'||str.back()=='-'||str.back()=='*'||str.back()=='/'||
str.back()=='%'||str.back()=='.'||str.back()=='(')
{
QMessageBox box;
box.setText("算式错误");
box.exec();
return 1;
}
return 0;
}
//历史记录
void Widget::on_button_history_clicked()
{
h.setext(QString::fromStdString(his_str));
h.exec();
}
mian.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}