QT 简单计算器

在这里插入图片描述

一、设计目标

设计一个支持连续计算的科学计算器。通过单击按钮,或者从文本框输入运算表达式,并完成计算,并且将结果显示出来。例如4*5+3,3+2/3,n的阶乘,x的y次幂,开平方,三角函数,log,ln,清除后退,显示历史记录等等。

二、算法分析

进行输入时直接输入到显示框上,当按下“=”按钮时读取显示框里的表达式,进行计算,并将结果输出到显示屏上。所以,计算器的核心算法就在于如何计算从显示屏上读取的中缀表达式。
计算中缀表达式需要用到两个栈Stack,一个作为数字栈number_stack,专门存储中缀表达式里面的数字,另一个是操作符栈operator_stack,用来存储操作符。核心算法是中缀表达式转成后缀表达式,然后计算后缀表达式,但是这俩个可以合起来一块计算。具体算法流程如下:
首先对涉及到的操作符设置优先级。从左至右依次读取中缀表达式,如果是数字(直接读出负数、小数、多于十位的数)则直接压入数字栈number_stack。如果是操作符(不包括左右括号),观察operator_stack是否为空,为空则直接压入栈,不为空则比较当前栈顶与此操作符的优先级。若此操作符优先级高则直接压入栈,否则弹出栈顶,并从数字栈number_stack弹出两个数字,第一个弹出的数字作为右操作数,第二个弹出的作为左操作数,与操作符运算并将结果压入栈。(若弹出的操作符为单目运算符,则只弹出一个数字)
如果碰到“(”直接入栈,碰到“)”从操作符栈operator_stack一直弹出,直到弹出“(”。到中缀表达式读取完后,看操作符栈operator_stack是否为空,不为空就依次弹出栈,直到为空。此时数字栈
number_satck剩余的一个数就是结果,将结果输出到显示屏上。
下面为流程图:
在这里插入图片描述

三、源代码

calculate.h

#ifndef CALCULATE_H
#define CALCULATE_H
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;

class calculate
{
public:
    calculate();
};
extern bool is_new;
extern bool is_minus;
extern double ans;
extern double e;
int getPriority(char ch);//得到运算符的优先级
void calculate(stack<double> &mystack, char operation);//根据操作符进行计算
double calculator(string str);//遍历表达式
#endif // CALCULATE_H

calculate.cpp

#include "calculate.h"
#include<iostream>
#include<string>
#include<stack>
#include<math.h>
using namespace std;
calculate::calculate()
{

}
bool is_new = false;
bool is_minus = false;
double ans = 0;
double e = 2.718281828459045;
double P = 3.14159265358979323846;
int getPriority(char ch)//得到运算符优先级
{
    if (ch == '+' || ch == '-') return 1;
    else if (ch == '*' || ch == '/') return 2;
    else if (ch == 's' || ch == 'c'|| ch == 't' || ch == 'i' || ch == 'o' || ch == 'a' || ch == '^' || ch == 'g' || ch == 'n' || ch == 'r' || ch == 'm') return 3;
    else if (ch == '!') return 4;
    else return 5;
}
void calculate(stack<double> &number, char tmp_operation)//运算符计算函数
{
    double num1, num2, num3;
    num2 = number.top();
    number.pop();
    if(tmp_operation == '!'){
        num3 = 1;
        while(num2>1){
            num3 *= num2;
            num2 --;
        }
    }
    else if(tmp_operation == 's' || tmp_operation == 'c' || tmp_operation == 't' || tmp_operation == 'i' || tmp_operation == 'o' || tmp_operation == 'a' || tmp_operation == 'g' || tmp_operation == 'n' || tmp_operation == 'r'){
        if(tmp_operation == 's')num3 = sin(num2);
        else if(tmp_operation == 'c')num3 = cos(num2);
        else if(tmp_operation == 't')num3 = tan(num2);
        else if(tmp_operation == 'i')num3 = asin(num2);
        else if(tmp_operation == 'o')num3 = acos(num2);
        else if(tmp_operation == 'a')num3 = atan(num2);
        else if(tmp_operation == 'g')num3 = log10(num2);
        else if(tmp_operation == 'n')num3 = log(num2);
        else if(tmp_operation == 'r')num3 = sqrt(num2);
    }
    else{
        num1 = number.top();
        number.pop();
        if (tmp_operation == '+') {
            num3 = num1 + num2;
        }
        else if (tmp_operation == '-') {
            num3 = num1 - num2;
        }
        else if (tmp_operation == '*') {
            num3 = num1 * num2;
        }
        else if (tmp_operation == '/') {
            num3 = num1 / num2;
        }
        else if (tmp_operation == '^') {
            num3 = pow(num1, num2);
        }
        else if (tmp_operation == 'm'){
            num3 = fmodf(num1, num2);
        }
    }
    number.push(num3);
}
double calculator(string str)//遍历表达式
{
    stack<double> number;
    stack<char> operation;
    int i = 0, j;
    int size = str.size();
    char tmp_operation;
    string num;
    string num0;
    while (i < size) {
        if (str[i] >= '0' && str[i] <= '9') {
            j = i;
            while ((j < size && str[j] >= '0' && str[j] <= '9') || str[j]=='.') { j++; }
            num = str.substr(i, j - i);
            if(!is_minus) number.push(atof(num.c_str()));
            else number.push(0-atof(num.c_str()));
            i = j;
        }
        else if (str[i] == 'A'){
            number.push(ans);
            i+=3;
        }
        else if(str[i] == 'e'){
            number.push(e);
            i++;
        }
        else if(str[i] == 'P'){
            number.push(P);
            i+=2;
        }
        else if(str[i] == '(' || str[i] == ')'){
            if (str[i] == '(') operation.push(str[i]);
            else {
                while (operation.top() != '(') {
                    tmp_operation = operation.top();
                    operation.pop();
                    calculate(number, tmp_operation);
                }
                operation.pop();
            }
            i++;
        }
        else if(str[i] == 's' || str[i] == 'c' || str[i] == 't'){
            if(str[i] == 's' && str[i+1] == 'q'){
                operation.push('r');
                i += 4;
            }
            else{
                operation.push(str[i]);
                i += 3;
            }
        }
        else if(str[i] == 'a'){
            if(str[i+3]=='s')operation.push('i');
            else if(str[i+3]=='c')operation.push('o');
            else if(str[i+3]=='t')operation.push('a');
            i += 6;
        }
        else if(str[i] == 'l'){
            if(str[i+1] == 'o'){operation.push('g');i+=3;}
            else if(str[i+1]=='n'){operation.push('n');i+=2;}
        }
        else{
            if(str[i]=='-' && (operation.empty() || operation.top()=='(')){
                is_minus = true;
            }
            else if (operation.empty()) {
                operation.push(str[i]);
            }
            else {
                while (!operation.empty()) {
                    tmp_operation = operation.top();
                    if (getPriority(tmp_operation) >= getPriority(str[i])) {
                        operation.pop();
                        calculate(number, tmp_operation);
                    }
                    else break;
                }
                operation.push(str[i]);
            }
            if(str[i] == 'm')i += 3;
            else i++;
        }
    }
    while (!operation.empty()) {
        tmp_operation = operation.top();
        operation.pop();
        calculate(number, tmp_operation);
    }
    return number.top();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<calculate.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_pushButton_mul_clicked();

    void on_pushButton_div_clicked();

    void on_pushButton_sub_clicked();

    void on_pushButton_add_clicked();

    void on_pushButton_pow_clicked();

    void on_pushButton_point_clicked();

    void on_pushButton_0_clicked();

    void on_pushButton_1_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_5_clicked();

    void on_pushButton_6_clicked();

    void on_pushButton_7_clicked();

    void on_pushButton_8_clicked();

    void on_pushButton_9_clicked();

    void on_pushButton_del_clicked();

    void on_pushButton_AC_clicked();

    void on_pushButton_equ_clicked();

    void on_pushButton_Ans_clicked();

    void on_pushButton_left_clicked();

    void on_pushButton_right_clicked();

    void on_pushButton_pi_clicked();

    void on_pushButton_sin_clicked();

    void on_pushButton_cos_clicked();

    void on_pushButton_tan_clicked();

    void on_pushButton_1x_clicked();

    void on_pushButton_n1_clicked();

    void on_pushButton_squ_clicked();

    void on_pushButton_e_clicked();

    void on_pushButton_arcsin_clicked();

    void on_pushButton_arccos_clicked();

    void on_pushButton_arctan_clicked();

    void on_pushButton_log_clicked();

    void on_pushButton_ln_clicked();

    void on_pushButton_x2_clicked();

    void on_pushButton_x3_clicked();

    void on_pushButton_ex_clicked();

    void on_pushButton_2x_clicked();

    void on_pushButton_mod_clicked();

    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QLineEdit>
#include<QString>
#include<QByteArray>
#include<stdlib.h>
#include"calculate.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->line, SIGNAL(editingFinished()), this, SLOT(on_pushButton_equ_clicked()));
    QFont font;
    font.setPointSize(16);
    ui->line->setFont(font);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_equ_clicked()
{
    string str = ui->line->text().toStdString();
    ans = calculator(str);
    ui->line->setText(QString::number(ans));
    is_new = true;
    ui->textEdit->append(QString::fromStdString(str) + "=" + QString::number(ans));
}
void Widget::on_pushButton_del_clicked()
{
    if(is_new){ui->line->setText("");}
    QString a = ui->line->text();
    if(a.right(6)=="arcsin" || a.right(6)=="arccos" || a.right(6)=="arctan") a.chop(6);
    else if(a.right(3)=="sin" || a.right(3)=="cos" || a.right(3)=="tan" || a.right(3)=="Ans" || a.right(3)=="mod" || a.right(3)=="log") a.chop(3);
    else if(a.right(4)=="sqrt") a.chop(4);
    else if(a.right(2)=="ln" || a.right(2)=="PI") a.chop(2);
    else a.chop(1);
    ui->line->setText(a);
    is_new = false;
}
void Widget::on_pushButton_mul_clicked()
{
   if(is_new){ui->line->setText("");}
   ui->line->setText(ui->line->text() +'*');
   is_new = false;
}
void Widget::on_pushButton_div_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'/');
    is_new = false;
}
void Widget::on_pushButton_sub_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'-');
    is_new = false;
}
void Widget::on_pushButton_add_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'+');
    is_new = false;
}
void Widget::on_pushButton_pow_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'^');
    is_new = false;
}
void Widget::on_pushButton_point_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'.');
    is_new = false;
}
void Widget::on_pushButton_0_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'0');
    is_new = false;
}
void Widget::on_pushButton_1_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'1');
    is_new = false;
}
void Widget::on_pushButton_2_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'2');
    is_new = false;
}
void Widget::on_pushButton_3_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'3');
    is_new = false;
}
void Widget::on_pushButton_4_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'4');
    is_new = false;
}
void Widget::on_pushButton_5_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'5');
    is_new = false;
}
void Widget::on_pushButton_6_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'6');
    is_new = false;
}
void Widget::on_pushButton_7_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'7');
    is_new = false;
}
void Widget::on_pushButton_8_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'8');
    is_new = false;
}
void Widget::on_pushButton_9_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'9');
    is_new = false;
}

void Widget::on_pushButton_AC_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText("");
    is_new = false;
}
void Widget::on_pushButton_Ans_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +"Ans");
    is_new = false;
}
void Widget::on_pushButton_left_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +'(');
    is_new = false;
}
void Widget::on_pushButton_right_clicked()
{
    if(is_new){ui->line->setText("");}
    ui->line->setText(ui->line->text() +')');
    is_new = false;
}
void Widget::on_pushButton_pi_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"PI");
}
void Widget::on_pushButton_sin_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"sin");
}
void Widget::on_pushButton_cos_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"cos");
}
void Widget::on_pushButton_tan_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"tan");
}
void Widget::on_pushButton_1x_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"1/");
}
void Widget::on_pushButton_n1_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"!");
}

void Widget::on_pushButton_squ_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"sqrt");
}

void Widget::on_pushButton_e_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +'e');
}

void Widget::on_pushButton_arcsin_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"arcsin");
}

void Widget::on_pushButton_arccos_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"arccos");
}

void Widget::on_pushButton_arctan_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"arctan");
}

void Widget::on_pushButton_log_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"log");
}

void Widget::on_pushButton_ln_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"ln");
}

void Widget::on_pushButton_x2_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"^2");
}

void Widget::on_pushButton_x3_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"^3");
}

void Widget::on_pushButton_ex_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"e^");
}

void Widget::on_pushButton_2x_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"2^");
}

void Widget::on_pushButton_mod_clicked()
{
    if(is_new){ui->line->setText("");}
    is_new = false;
    ui->line->setText(ui->line->text() +"mod");
}

void Widget::on_pushButton_clicked()
{
    ui->textEdit->setText("");
}

四、源代码下载

下载链接

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值