QT5 实现简易科学计算器

界面展示

主界面
基础科学计算器界面
矩阵计算界面

功能叙述

              \;\;\;\;\;\;\, 基础计算界面允许加减乘除表达式计算及嵌套,以及一部分基本初等函数的数值计算,基本初等函数不允许嵌套函数及表达式,这个是此计算器的缺点
              \;\;\;\;\;\;\, 矩阵计算模块会实时根据行列输入生成对应表格,并给出行号和列号,并且第二个矩阵会根据第一个矩阵的行列自动创建,无需第二次输入行列数。缺点:作为右操作数的矩阵若不填满会导致程序异常终止,乘法的右操作数矩阵无法改变列数,时间仓促,待有时间进行修改

源码

主界面源码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDateTime>
#include <QTimer>
#include "matrixfunction.h"
#include "floatcanculator.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:


    void timerUpdate(void);

signals:
    void showFloat();

private slots:

    void on_floatCanculate_clicked();

    void on_MatrixCalculate_clicked();

private:
    Ui::MainWindow *ui;

};
#endif // MAINWINDOW_H

mainwindow.cpp

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


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    FloatCanculator backFloat;
    connect(&backFloat , SIGNAL(FloatToMain()) , this , SLOT(ReveiveFloat()));

    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
    timer->start(1000);
}

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

void MainWindow::on_floatCanculate_clicked()
{
    FloatCanculator jump;
    jump.exec();
}
//void MainWindow::ReceiveFloat()
//{
//    this->show();
//}
void MainWindow::timerUpdate(void)
{
    QDateTime time = QDateTime::currentDateTime();
    QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");
    ui->Time->setText(str);
}

void MainWindow::on_MatrixCalculate_clicked()
{
    MatrixFunction jump;
    jump.exec();
}

基础计算界面

floatcanculator.h

#ifndef FLOATCANCULATOR_H
#define FLOATCANCULATOR_H

#include <QDialog>
#include <QLabel>
#include <QTimer>
#include <QDateTime>
#include <string>
#include "legalexpression.h"
#include "Function.h"
#include <QDebug>

using namespace std;

namespace Ui {
class FloatCanculator;
}

class FloatCanculator : public QDialog
{
    Q_OBJECT

public:
    explicit FloatCanculator(QWidget *parent = nullptr);
    ~FloatCanculator();
public slots:
    void timerUpdate(void);

private slots:
    void on_SinButton_clicked();

    void on_CosButton_clicked();

    void on_TanButton_clicked();

    void on_lnButton_clicked();

    void on_SevenButton_clicked();

    void on_FourButton_clicked();

    void on_OneButton_clicked();

    void on_EightButton_clicked();

    void on_FiveButton_clicked();

    void on_TwoButton_clicked();

    void on_ZeroButton_clicked();

    void on_NineButton_clicked();

    void on_SixButton_clicked();

    void on_ThreeButton_clicked();

    void on_DotButton_clicked();

    void on_DivisionButton_clicked();

    void on_MultiplyButton_clicked();

    void on_SubtractionButton_clicked();

    void on_PlusButton_clicked();

    void on_EqualButton_clicked();

    void on_ClearButton_clicked();

    void on_RightBracketButton_clicked();

    void on_LeftBrakerButton_clicked();

    void on_ExpButton_clicked();

    void on_DoubleZeroButton_clicked();

    void on_BackUpButton_clicked();

    void on_PowerButton_clicked();

    void on_SqrtButton_clicked();

    void on_LgButton_clicked();

    void on_FactorialButton_clicked();

signals:
    void FloatToMain();

private:
    Ui::FloatCanculator *ui;
    QLabel *Time;
    QLabel *LabelExpression;
    enum FunctionSituation{EMPTY = 0,POWER,SQRT,LG,FAC,SIN,COS,TAN,LN,EXP,NUM};
    int Flag;

    bool JudgeIllgalInput();
    void moveCursor();
};

#endif // FLOATCANCULATOR_H

floatcanculator.cpp

#include "floatcanculator.h"
#include "ui_floatcanculator.h"
#include "mainwindow.h"
#include "Beh.hpp"
#include "Expression.hpp"
#include "Stack.hpp"

FloatCanculator::FloatCanculator(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::FloatCanculator)
{
    ui->setupUi(this);
    Time = new QLabel(this);
    LabelExpression = new QLabel(this);

    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
    timer->start(1000);

    Flag = EMPTY;
}

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

void FloatCanculator::timerUpdate()
{
    QDateTime time = QDateTime::currentDateTime();
    QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");
    Time->setText(str);
    Time->setAlignment(Qt::AlignLeft);
    Time->setGeometry(0,0,580,80);
    QFont font;
    font.setItalic(true);
    font.setPixelSize(30);
    Time->setFont(font);
    Time->show();
}
void FloatCanculator::on_SinButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("sin()");
    if(JudgeIllgalInput())
    {
        Flag = SIN;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_CosButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("cos()");
    JudgeIllgalInput();
    if(JudgeIllgalInput())
    {
        Flag = COS;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_TanButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("tan()");
    if(JudgeIllgalInput())
    {
        Flag = TAN;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_lnButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("ln()");
    if(JudgeIllgalInput())
    {
        Flag = LN;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_SevenButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("7");
}

void FloatCanculator::on_FourButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("4");
}

void FloatCanculator::on_OneButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("1");
}

void FloatCanculator::on_EightButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("8");
}

void FloatCanculator::on_FiveButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("5");
}

void FloatCanculator::on_TwoButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("2");
}

void FloatCanculator::on_ZeroButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("0");
}

void FloatCanculator::on_NineButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("9");
}

void FloatCanculator::on_SixButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("6");
}

void FloatCanculator::on_ThreeButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("3");
}

void FloatCanculator::on_DotButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert(".");
}

void FloatCanculator::on_DivisionButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("/");
}

void FloatCanculator::on_MultiplyButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("*");
}

void FloatCanculator::on_SubtractionButton_clicked()
{

    LabelExpression->clear();
    ui->Display->insert("-");
}

void FloatCanculator::on_PlusButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("+");
}

void FloatCanculator::on_EqualButton_clicked()
{
    double Answer = 0;
    LabelExpression->clear();
    // 按下等号获取当前QLineEdit中的字符串,并转化为string类型
    QString QExpression = ui->Display->text();
    string expressions = QExpression.toStdString();
    // 判断表达式是否合法
    LegalExpression Judger(expressions);
    if(Judger.isLegal())
    {
        if(Flag != EMPTY)
        {
            // 在这里直接进入函数泰勒计算
            // enum FunctionSituation{EMPTY = 0,POWER,SQRT,LG,FAC,SIN,COS,TAN,LN,EXP};
            switch (Flag)
            {
                case POWER:
                {
                    int Length = QExpression.length();
                    int position = QExpression.indexOf("∧");

                    QString QbaseNumber = QExpression;
                    QbaseNumber.chop(Length - position);
                    double baseNumber = QbaseNumber.toDouble();

                    QString QpowNumber = QExpression.mid(position+2);
                    QpowNumber.chop(1);
                    double powNumber = QpowNumber.toDouble();

                    Answer = getPow(baseNumber , powNumber);
                    break;
                }
                case SQRT:
                {
                    QString Qnumber = QExpression.mid(2);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getSqrt(number);
                    break;
                }
                case LG:
                {
                    QString Qnumber = QExpression.mid(3);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getLg(number);
                    break;
                }
                case FAC:
                {
                    QString Qnumber = QExpression;
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getFac(number);
                    break;
                }
                case SIN:
                {
                    QString Qnumber = QExpression.mid(4);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getSin(number);
                    break;
                }
                case COS:
                {
                    QString Qnumber = QExpression.mid(4);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getCos(number);
                    break;
                }
                case TAN:
                {
                    QString Qnumber = QExpression.mid(4);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getTan(number);
                    break;
                }
                case LN:
                {
                    QString Qnumber = QExpression.mid(3);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getLn(number);
                    break;
                }
                case EXP:
                {
                    QString Qnumber = QExpression.mid(4);
                    Qnumber.chop(1);
                    double number = Qnumber.toDouble();

                    Answer = getExp(number);
                    break;
                }
                default:
                    break;
            }
        }
        else
        {
            //接口留在这里,串联后端构建表达式以及输出表达式Q
            expressions += "#";
            Expression *get = strToTree( expressions );
            ui->Display->clear();
            Answer = getResult( get );             // 用这个参数接返回的计算值
        }


        QString QAnswer = QString::number(Answer , 10 , 6);
        ui->Display->setText(QAnswer);

        LabelExpression->setText(QExpression);
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    else
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }

}

void FloatCanculator::on_ClearButton_clicked()
{
    LabelExpression->clear();
    ui->Display->clear();
    Flag = EMPTY;
    ui->Display->setEnabled(true);
}

void FloatCanculator::on_RightBracketButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("(");
    JudgeIllgalInput();
    Flag = NUM;
}


void FloatCanculator::on_LeftBrakerButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert(")");
    Flag = NUM;
}

bool FloatCanculator::JudgeIllgalInput()
{
    bool ReturnJudge = true;


    QString expression = ui->Display->text();
    string stdExpression = expression.toStdString();
    //接口
    //返回值
    LegalExpression Judger(stdExpression);
    ReturnJudge = Judger.isLegal();
    if(!ReturnJudge)
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    return ReturnJudge;
}

void FloatCanculator::moveCursor()
{
    QString text = ui->Display->text();
    int position = text.indexOf(")");

    if(position != -1)
        ui->Display->setCursorPosition(position);
}

void FloatCanculator::on_ExpButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("exp()");
    if(JudgeIllgalInput())
    {
        Flag = EXP;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}


void FloatCanculator::on_DoubleZeroButton_clicked()
{
    LabelExpression->clear();
    ui->Display->insert("00");
    JudgeIllgalInput();
    Flag = NUM;
}

void FloatCanculator::on_BackUpButton_clicked()
{
    QString text;
    text = ui->Display->text();

    int Length = text.length();
    text = text.mid(0,Length-1);
    ui->Display->setText(text);
    LabelExpression->clear();
    if(Flag != NUM)
        Flag = EMPTY;
    ui->Display->setEnabled(true);
}

void FloatCanculator::on_PowerButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("∧()");

    QString text;
    text = ui->Display->text();

    QString preString = text;
    preString.chop(3);

    bool isNumber = true;
    double tempTest = preString.toDouble(&isNumber);

    if(!isNumber)
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    else
    {
        Flag = POWER;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_SqrtButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("√()");

    QString text = ui->Display->text();

    if(text.at(0) != "√")
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    else
    {
        Flag = SQRT;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_LgButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("lg()");

    QString text = ui->Display->text();

    if(text.at(1) != "g")
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    else
    {
        Flag = LG;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

void FloatCanculator::on_FactorialButton_clicked()
{
    if(Flag != EMPTY)
        return;
    LabelExpression->clear();
    ui->Display->insert("!");

    QString text = ui->Display->text();

    QString preString = text;
    preString.chop(1);
    bool isNumber = true;

    double temp = preString.toDouble(&isNumber);

    if(!isNumber)
    {
        LabelExpression->setText("错误计算格式,请修改");
        LabelExpression->setAlignment(Qt::AlignRight);
        LabelExpression->setGeometry(581 , 0 , 580 , 80);

        QFont font;
        font.setPixelSize(30);

        LabelExpression->setFont(font);
        LabelExpression->show();
    }
    else
    {
        Flag = FAC;
        moveCursor();
        ui->Display->setFocusPolicy(Qt::NoFocus);
    }
}

Beh.hpp

#pragma once
#define _BEH_HPP_

#include <stdio.h>
#include <stdlib.h>
#include <string>

#include "Stack.hpp"
#include "Expression.hpp"

double strToDouble( std::string str, int n ) {
    double ret = 0.0; int dotMarker = 0;
    for ( int i = 0; i < n; i++ ) {
        if ( '.' == str[i] ) dotMarker = i;
        else {
            ret = ret * 10 + str[i] - '0';
        }
    }
    if ( 0 != dotMarker ) {
        for ( int i = 1; i < n - dotMarker; i++ ) {
            ret /= 10;
        }
    }
    return ret;
} // 字符串转数值,支持小数

char Prior[8][8] = { // 运算符优先级表 
	//      '+'  '-'  '*'  '/'  '('  ')'  '#'  '^'
	/*'+'*/ '>', '>', '<', '<', '<', '>', '>', '<', 
	/*'-'*/ '>', '>', '<', '<', '<', '>', '>', '<', 
	/*'*'*/ '>', '>', '>', '>', '<', '>', '>', '<', 
	/*'/'*/ '>', '>', '>', '>', '<', '>', '>', '<', 
	/*'('*/ '<', '<', '<', '<', '<', '=', ' ', '<', 
	/*')'*/ '>', '>', '>', '>', ' ', '>', '>', '>', 
	/*'#'*/ '<', '<', '<', '<', '<', ' ', '=', '<', 
	/*'^'*/ '>', '>', '>', '>', '<', '>', '>', '>' 
};

char getPrior( char prev, char curr ) {
    int i; int j; // 前一个操作已在栈中 // 当前运算符
    switch (prev) {
        case '+': i = 0; break;
        case '-': i = 1; break;
        case '*': i = 2; break;
        case '/': i = 3; break;
        case '(': i = 4; break;
        case ')': i = 5; break;
        case '#': i = 6; break;
        case '^': i = 7; break;
        default: break;
    }
    switch (curr) {
        case '+': j = 0; break;
        case '-': j = 1; break;
        case '*': j = 2; break;
        case '/': j = 3; break;
        case '(': j = 4; break;
        case ')': j = 5; break;
        case '#': j = 6; break;
        case '^': j = 7; break;
        default: break;
    }
    return Prior[i][j];
}

Expression* strToTree( std::string& str ) {
    Stack<char> optrStack; // 运算符栈
    Stack<Expression*> opndStack; // 运算数栈

    PushIntoStack( &optrStack, '#' ); // 先将#入栈,优先级最低,结尾必有#

    int i = 0;
    while ( i < str.length() ) {
        if ( str[i] >= '0' && str[i] <= '9' ) {
            std::string temp;
            while ( true ) {
                if ( !(str[i] >= '0' && str[i] <= '9') && str[i] != '.' ) {
                    break;
                }
                temp.push_back(str[i]);
                i++;
            }
            Expression* ptr = new Operand( strToDouble( temp, temp.length() ) );
            PushIntoStack( &opndStack, ptr );
        } // 为数字,建立叶子节点并暂存
        else {

            // 总原则
            // 高优先级的二叉树先建立:后入栈,先出栈
            // 低优先级的二叉树后建立:先入栈,后出栈
            // 栈顶元素 : 当前元素

            switch (
                getPrior( DisplayTopItem( &optrStack ), str[i] )
            ) {
                case '<': {
                    PushIntoStack( &optrStack, str[i] );
                    i++;
                    break;
                }
                case '=': {
                    char temp;
                    PopFromStack( &optrStack, &temp );
                    i++;
                    break;
                } // 脱括号或者#
                case '>': {
                    char temp;
                    PopFromStack( &optrStack, &temp );
                    Expression* rptr; PopFromStack( &opndStack, &rptr );
                    Expression* lptr; PopFromStack( &opndStack, &lptr );
                    Expression* ptr = new Operator( lptr, rptr, temp );
                    PushIntoStack( &opndStack, ptr );
                    break;
                }
                default: break;
            }
        }
    }
    Expression* ptr;
    PopFromStack( &opndStack, &ptr );
    return ptr;
}

Expression.hpp

#pragma once
#define _EXPRESSION_HPP_

#include <stdio.h>
#include <stdlib.h>

class Expression {

public:
    Expression() {
        leftChild = rightChild = NULL;
    }
    Expression(
        Expression* theLeftChild, Expression* theRightChild
    ) {
        leftChild = theLeftChild;
        rightChild = theRightChild;
    } // 构造函数的重载

public:
    Expression* leftChild; Expression* rightChild;

};

class Operand : public Expression { // 操作数类 
    friend double getResult( Expression* ptr );
    friend void OutputInorder( Expression* out );

public:
    Operand( double value ) {
        leftChild = rightChild = NULL;
        this ->value = value;
    }

private:
    double value;

};

class Operator : public Expression { // 运算符类

    friend double getResult( Expression* ptr );
    friend void OutputInorder( Expression* out );

public:
    Operator(
        Expression* theLeftChild, Expression* theRightChild, char Type
    ) {
        leftChild = theLeftChild;
        rightChild = theRightChild;
        type = Type;
    } // 基类的指针实现多态

private:
    char type;
    
};

double getResult( Expression* ptr ) { // 对二叉树后序遍历
    double leftResult = 0, rightResult=0;
    
    if ( ptr ->leftChild )
        leftResult = getResult(ptr ->leftChild);
    else
        return ((Operand*)ptr) ->value;

    if ( ptr ->rightChild )
        rightResult = getResult(ptr ->rightChild);
    else
        return ((Operand*)ptr) ->value;

    switch (
        ((Operator*)ptr) ->type
    ) {
        case '+': return leftResult + rightResult;
        case '-': return leftResult - rightResult;
        case '*': return leftResult * rightResult;
        case '/': return leftResult / rightResult;
    }
    return 0;
}

void OutputInorder( Expression* out ) {
    if ( out ->leftChild )
        OutputInorder(out ->leftChild);
    else
        printf("%lf", ((Operand*)out) ->value);

    printf("%c", ((Operator*)out) ->type);

    if ( out ->rightChild )
        OutputInorder(out ->rightChild);
    else
        printf("%lf", ((Operand*)out) ->value);
}

Stack.hpp

#pragma once
#define _STACK_HPP_

#include <stdio.h>
#include <stdlib.h>

enum State {
    ERROR, COMPLETE
};

#define MAX_SIZE 100

template<typename T>
struct Stack {
    T dataStorage[MAX_SIZE];
    int topPtr = -1;
};

template<typename T>
int GetTopPtr( Stack<T>* ptr ) {
    return ptr ->topPtr;
}

template<typename T>
bool isFull( Stack<T>* ptr ) {
    bool ret = false;
    if ( MAX_SIZE - 1 == ptr ->topPtr ) ret = true;
    return ret;
}

template<typename T>
bool isEmpty( Stack<T>* ptr ) {
    bool ret = false;
    if ( -1 == ptr ->topPtr ) ret = true;
    return ret;
}

template<typename T>
State PushIntoStack( Stack<T>* ptr, T item ) {
    if ( MAX_SIZE - 1 == ptr ->topPtr ) {
        return State::ERROR;
    }
    else {
        (ptr ->dataStorage)[++ptr ->topPtr] = item;
        return State::COMPLETE;
    }
}

template<typename T>
State PopFromStack( Stack<T>* ptr, T* item ) {
    if ( -1 == ptr ->topPtr ) {
        return State::ERROR;
    }
    else {
        ptr ->topPtr --;
        *item = (ptr ->dataStorage)[ptr ->topPtr + 1];
        return State::COMPLETE;
    }
}

template<typename T>
T DisplayTopItem( Stack<T>* ptr ) {
    return (ptr ->dataStorage)[ptr ->topPtr];
}

Function.h

#ifndef FUNCTION_H
#define FUNCTION_H

#include <iostream>
#include <string>
#include <math.h>

using namespace std;

double getSin(double number);
double getCos(double number);
double getTan(double number);
double getLn(double number);
double getExp(double number);
double getPow(double baseNumber , double powNumber);
double getSqrt(double number);
double getLg(double number);
double getFac(double number);

#endif // FUNCTION_H

Function.cpp

#include "Function.h"

double getSin(double number)
{
    double answer = 0;
    // 弧度
    double radian = (number * 3.1415926) / 180.0;
    answer = sin(radian);

    return answer;
}

double getCos(double number)
{
    double answer = 0;
    // 弧度
    double radian = (number * 3.1415926) / 180.0;
    answer = cos(radian);

    return answer;
}

double getTan(double number)
{
    double answer = 0;
    // 弧度
    double radian = (number * 3.1415926) / 180.0;
    answer = tan(radian);

    return answer;
}

double getLn(double number)
{
    double answer = 0;

    answer = log(number);

    return answer;
}

double getExp(double number)
{
    double answer = 0;

    answer = exp(number);

    return answer;
}

double getSqrt(double number)
{
    double answer = 0;

    answer = sqrt(number);

    return answer;
}

double getLg(double number)
{
    double answer = 0;

    answer = log10(number);

    return answer;
}

double getFac(double number)
{
    double answer = 1;

    for (double i = 2; i <= number; ++i)
    {
        answer *= i;
    }

    return answer;
}

double getPow(double baseNumber, double powNumber)
{
    double answer = 0;

    answer = pow(baseNumber, powNumber);

    return answer;
}

legalexpression.h

#ifndef LEGAL_EXPRESSION_H
#define LEGAL_EXPRESSION_H

#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>

using namespace std;

#define INIT_STACK_SIZE 101

class LegalExpression
{

public:

    LegalExpression();
    LegalExpression(string expression);
    virtual ~LegalExpression();

    bool isLegal();		// 如果合法,返回true
    void Push(char in);
    void Pop(char& out);

    struct ExpressionStack
    {
        char* topPointer;
        char* basePointer;
        int stackSize;
    };

private:

    string expression;
    const char* c_expression = NULL;
    ExpressionStack stack;

};


#endif // !LEGAL_EXPRESSION_H

legalexpression.cpp

#include "LegalExpression.h"

LegalExpression::LegalExpression()
{
    c_expression = NULL;
}

LegalExpression::LegalExpression(string expression)
{
    this->expression = expression;
    c_expression = this->expression.c_str();
    // 初始化栈
    stack.basePointer = (char*)malloc(sizeof(char) * INIT_STACK_SIZE);
    if (!stack.basePointer)
        exit(OVERFLOW);
    stack.topPointer = stack.basePointer;

    stack.stackSize = INIT_STACK_SIZE;
}

LegalExpression::~LegalExpression()
{
    stack.topPointer = NULL;
    delete[] stack.basePointer;
}

bool LegalExpression::isLegal()
{
    bool ReturnJudge = true;

    int Length = expression.length();

    // 0为无操作正在等待,1为有特殊操作等待
    int Flag = 0;

    for (int i = 0; i < Length; ++i)
    {
        switch (Flag)
        {
            case 0:
            {
                if (c_expression[i] == ')')
                {
                    Flag = 1;
                    continue;
                }
                else if (c_expression[i] == 'l')
                {
                    Flag = 2;
                }
                else if (c_expression[i] == 's')
                {
                    Flag = 2;
                }
                else if (c_expression[i] == 'c')
                {
                    Flag = 2;
                }
                else if (c_expression[i] == 't')
                {
                    Flag = 2;
                }
                Push(c_expression[i]);
                break;
            }
            case 1:
            {
                char out;
                Pop(out);
                while (out != '(')
                {
                    Pop(out);
                }
                // 括号连续并且没有符号作为间隔
                if (c_expression[i] == '(')
                {
                    ReturnJudge = false;
                    return ReturnJudge;
                }
                else if (c_expression[i] >= 'a' && c_expression[i] <= 'z')
                {
                    ReturnJudge = false;
                    return ReturnJudge;
                }
                Push(c_expression[i]);
                break;
            }
            case 2:
            {
                if (c_expression[i] == ')')
                {
                    Flag = 3;
                    continue;
                }
                Push(c_expression[i]);
                break;
            }
            case 3:
            {
                char out;
                Pop(out);
                while (out != '(')
                {
                    Pop(out);
                }
                if (c_expression[i] >= 'a' && c_expression[i] <= 'z')
                {
                    ReturnJudge = false;
                    return ReturnJudge;
                }
                else if (c_expression[i] == '(')
                {
                    ReturnJudge = false;
                    return ReturnJudge;
                }
                Push(c_expression[i]);
                Flag = 2;
                break;
            }
            default:
                break;
        }
    }

    return ReturnJudge;
}

void LegalExpression::Push(char in)
{
    *stack.topPointer++ = in;
}

void LegalExpression::Pop(char& out)
{
    out = *--stack.topPointer;
}

矩阵计算界面

matrixfunction.h

#ifndef MATRIXFUNCTION_H
#define MATRIXFUNCTION_H

#include <QDialog>
#include <QTimer>
#include <QDateTime>
#include <QLabel>
#include <QHeaderView>

#define MAXROW 20
#define MAXCOLUMN 20

namespace Ui {
class MatrixFunction;
}

class MatrixFunction : public QDialog
{
    Q_OBJECT

public:
    explicit MatrixFunction(QWidget *parent = nullptr);
    ~MatrixFunction();

    typedef struct noname{
        double value[MAXROW][MAXCOLUMN];
        int row;
        int column;
    }QMatrix;

    QMatrix left;
    QMatrix right;
    QMatrix answer;


public slots:

    void timerUpdate(void);
    void makeTable();


private slots:

    void on_PlusButton_clicked();

    void on_SubstractButton_clicked();

    void on_MultiplyButton_clicked();

    void on_ClearButton_clicked();

    void on_EqualsButton_clicked();

private:
    Ui::MatrixFunction *ui;

    QLabel *Time;
    QLabel *LabelExpression;

    QTimer *timer;
    QTimer *readTimer;

    enum Function{EMPTY , PLUS , SUB , MUL};

    int Flag;

    void setWrongLabel(QString message);

    void getAdd();
    void getSub();
    void getMul();
};

#endif // MATRIXFUNCTION_H

matrixfunction.cpp

#include "matrixfunction.h"
#include "ui_matrixfunction.h"

MatrixFunction::MatrixFunction(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MatrixFunction)
{
    ui->setupUi(this);

    Time = new QLabel(this);
    LabelExpression = new QLabel(this);

    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
    timer->start(1000);

    readTimer = new QTimer(this);
    connect(readTimer , SIGNAL(timeout()) , this , SLOT(makeTable()));
    readTimer->start(1000);

    for(int i = 0 ; i < MAXROW ; ++i)
    {
        for(int j = 0 ; j < MAXCOLUMN ; ++j)
        {
            left.value[i][j] = 0;
            right.value[i][j] = 0;
            answer.value[i][j] = 0;
        }
    }
    left.row = right.row = answer.row =  0;
    left.column = right.column = answer.column = 0;

    Flag = EMPTY;
}

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

void MatrixFunction::timerUpdate()
{
    QDateTime time = QDateTime::currentDateTime();
    QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");
    Time->setText(str);
    Time->setAlignment(Qt::AlignLeft);
    Time->setGeometry(0,0,580,80);
    QFont font;
    font.setItalic(true);
    font.setPixelSize(30);
    Time->setFont(font);
    Time->show();
}

void MatrixFunction::makeTable()
{
    LabelExpression->clear();
    int Row , Column;
    bool judgeRow = true , judgeColumn = true;
    Row = ui->RowMatrix->text().toInt(&judgeRow);
    Column = ui->ColumnMatrix->text().toInt(&judgeColumn);

    if(judgeRow && judgeColumn)
    {
        ui->Display->verticalHeader()->hide();
        ui->Display->horizontalHeader()->hide();
        ui->Display->setRowCount(Row+1);
        ui->Display->setColumnCount(Column+1);
        for(int i = 0 ; i < Row ; i++)
        {
            ui->Display->setItem(i+1,0,new QTableWidgetItem(QString::number(i+1 , 10)));
        }
        for(int i = 0 ; i < Column ; ++i)
        {
            ui->Display->setItem(0,i+1,new QTableWidgetItem(QString::number(i+1 , 10)));
        }

        for(int i = 0 ; i <= Row ; ++i)
            ui->Display->setRowHeight(i,50);
        for(int i = 0 ; i <= Column ; ++i)
            ui->Display->setColumnWidth(i,50);
    }
    else if(ui->RowMatrix->text() == NULL && ui->ColumnMatrix->text() == NULL)
    {
    }
    else
    {
        ui->Display->clear();
        setWrongLabel("错误行列数目格式,请修改");
    }


}

void MatrixFunction::setWrongLabel(QString message)
{
    LabelExpression->setText(message);
    LabelExpression->setAlignment(Qt::AlignRight);
    LabelExpression->setGeometry(581 , 0 , 580 , 80);

    QFont font;
    font.setPixelSize(30);

    LabelExpression->setFont(font);
    LabelExpression->show();
}

void MatrixFunction::MatrixFunction::getAdd()
{
    for(int i = 0 ; i <= answer.row ; ++i)
    {
        for(int j = 0 ; j <= answer.column ; ++j)
        {
            answer.value[i][j] = left.value[i][j] + right.value[i][j];
        }
    }
}

void MatrixFunction::getSub()
{
    for(int i = 0 ; i <= answer.row ; ++i)
    {
        for(int j = 0 ; j <= answer.column ; ++j)
        {
            answer.value[i][j] = left.value[i][j] - right.value[i][j];
        }
    }
}

void MatrixFunction::getMul()
{
    int limit = left.column;
    for(int i = 0 ; i <= answer.row ; ++i)
    {
        for(int j = 0 ; j <= answer.column ; ++j)
        {
            double sum = 0;
            for ( int k = 0; k <= limit; k++ )
            {
                sum += left.value[i][k] * right.value[k][j];
            }
            answer.value[i][j] = sum;
        }
    }
}

void MatrixFunction::on_PlusButton_clicked()
{
    readTimer->stop();
    int row = ui->RowMatrix->text().toInt();
    int column = ui->ColumnMatrix->text().toInt();
    bool Judge = true;              //true说明填满了

    for(int i = 1 ; i <= row ; ++i)
    {
        for(int j = 1 ; j <= column ; ++j)
        {
            if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
            {
                Judge = false;
                break;
            }
            else
                left.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
        }
        if(!Judge)
            break;
    }
    if(Judge)
    {
        left.row = row-1;
        left.column = column-1;

        ui->Display->clear();

        makeTable();
        ui->RowMatrix->clear();
        ui->ColumnMatrix->clear();

        Flag = PLUS;
    }
    else
    {
        setWrongLabel("矩阵未写满,请填满后点击操作符");
    }

}

void MatrixFunction::on_SubstractButton_clicked()
{
    readTimer->stop();
    int row = ui->RowMatrix->text().toInt();
    int column = ui->ColumnMatrix->text().toInt();
    bool Judge = true;

    for(int i = 1 ; i <= row ; ++i)
    {
        for(int j = 1 ; j <= column ; ++j)
        {
            if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
            {
                Judge = false;
                break;
            }
            else
                left.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
        }
        if(!Judge)
            break;
    }
    if(Judge)
    {
        left.row = row-1;
        left.column = column-1;

        ui->Display->clear();

        makeTable();
        ui->RowMatrix->clear();
        ui->ColumnMatrix->clear();

        Flag = SUB;
    }
    else
    {
        setWrongLabel("矩阵未写满,请填满后点击操作符");
    }
}

void MatrixFunction::on_MultiplyButton_clicked()
{
    readTimer->stop();
    int row = ui->RowMatrix->text().toInt();
    int column = ui->ColumnMatrix->text().toInt();
    bool Judge = true;

    for(int i = 1 ; i <= row ; ++i)
    {
        for(int j = 1 ; j <= column ; ++j)
        {
            if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
            {
                Judge = false;
                break;
            }
            else
                left.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
        }
        if(!Judge)
            break;
    }
    if(Judge)
    {
        left.row = row-1;
        left.column = column-1;

        ui->Display->clear();

        LabelExpression->clear();
        int Row , Column;
        Column = ui->RowMatrix->text().toInt();
        Row = ui->ColumnMatrix->text().toInt();
        ui->Display->verticalHeader()->hide();
        ui->Display->horizontalHeader()->hide();
        ui->Display->setRowCount(Row+1);
        ui->Display->setColumnCount(Column+1);
        for(int i = 0 ; i < Row ; i++)
        {
            ui->Display->setItem(i+1,0,new QTableWidgetItem(QString::number(i+1 , 10)));
        }
        for(int i = 0 ; i < Column ; ++i)
        {
            ui->Display->setItem(0,i+1,new QTableWidgetItem(QString::number(i+1 , 10)));
        }
        for(int i = 0 ; i <= Row ; ++i)
            ui->Display->setRowHeight(i,50);
        for(int i = 0 ; i <= Column ; ++i)
            ui->Display->setColumnWidth(i,50);
        Flag = MUL;
    }
    else
    {
        setWrongLabel("矩阵未写满,请填满后点击操作符");
    }
}

void MatrixFunction::on_ClearButton_clicked()
{
    ui->Display->clear();
    ui->RowMatrix->clear();
    ui->ColumnMatrix->clear();

    for(int i = 0 ; i < left.row ; ++i)
    {
        for(int j = 0 ; j < left.column ; ++j)
        {
            left.value[i][j] = 0;
        }
    }

    left.row = 0;
    left.column = 0;

    for(int i = 0 ; i < right.row ; ++i)
    {
        for(int j = 0 ; j < right.column ; ++j)
        {
            right.value[i][j] = 0;
        }
    }

    right.row = 0;
    right.column = 0;

    for(int i = 0 ; i < answer.row ; ++i)
    {
        for(int j = 0 ; j < answer.column ; ++j)
        {
            answer.value[i][j] = 0;
        }
    }

    answer.row = 0;
    answer.column = 0;

    readTimer->start();
}

void MatrixFunction::on_EqualsButton_clicked()
{
    int row = 0;
    int column = 0;
    bool Judge = true;

    switch (Flag)
    {
        case EMPTY:
        {

            break;
        }
        case PLUS:
        {
            row = left.row+1;
            column = left.column+1;


            for(int i = 1 ; i <= row ; ++i)
            {
                for(int j = 1 ; j <= column ; j++)
                {
                    if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
                    {
                        Judge = false;
                        break;
                    }
                    right.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
                }
                if(!Judge)
                    break;
            }
            if(Judge)
            {
                right.row = left.row;
                right.column = right.row;
                //在这里执行加法操作,结构体看.h文件,在public里面,返回值赋值给answer
                answer.row = left.row;
                answer.column = left.column;
                getAdd();
            }
            else
            {
                setWrongLabel("矩阵未写满,请填满后点击操作符");
            }
            break;
        }
        case MUL:
        {
            row = left.column+1;
            column = left.row+1;


            for(int i = 1 ; i <= row ; ++i)
            {
                for(int j = 1 ; j <= column ; j++)
                {
                    if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
                    {
                        Judge = false;
                        break;
                    }
                    right.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
                }
                if(!Judge)
                    break;
            }
            if(Judge)
            {
                right.row = row;
                right.column = column;
                //在这里执行乘法操作,结构体看.h文件,在public里面,返回值赋值给answer
                answer.row = left.row;
                answer.column = left.row;
                getMul();
            }
            else
            {
                setWrongLabel("矩阵未写满,请填满后点击操作符");
            }
            break;
        }
        case SUB:
        {
            row = left.row+1;
            column = left.column+1;


            for(int i = 1 ; i <= row ; ++i)
            {
                for(int j = 1 ; j <= column ; j++)
                {
                    if(ui->Display->item(i,j) == NULL || ui->Display->item(i,j)->text() == "")
                    {
                        Judge = false;
                        break;
                    }
                    right.value[i-1][j-1] = ui->Display->item(i,j)->text().toDouble();
                }
                if(!Judge)
                    break;
            }
            if(Judge)
            {
                right.row = row;
                right.column = column;
                //在这里执行减法操作,结构体看.h文件,在public里面,返回值赋值给answer
                answer.row = left.row;
                answer.column = left.column;
                getSub();
            }
            else
            {
                setWrongLabel("矩阵未写满,请填满后点击操作符");
            }
            break;
        }
        default:
            break;
     }

    ui->Display->clear();
    row = answer.row+1;
    column = answer.column+1;
    ui->Display->verticalHeader()->hide();
    ui->Display->horizontalHeader()->hide();
    ui->Display->setRowCount(row+1);
    ui->Display->setColumnCount(column+1);
    for(int i = 0 ; i < row ; i++)
    {
        ui->Display->setItem(i+1,0,new QTableWidgetItem(QString::number(i+1 , 10)));
    }
    for(int i = 0 ; i < column ; ++i)
    {
        ui->Display->setItem(0,i+1,new QTableWidgetItem(QString::number(i+1 , 10)));
    }
    for(int i = 0 ; i < row ; ++i)
        ui->Display->setRowHeight(i,50);
    for(int i = 0 ; i < column ; ++i)
        ui->Display->setColumnWidth(i,50);

    for(int i = 0 ; i <= answer.row ; ++i)
    {
        for(int j = 0 ; j <= answer.column ; ++j)
        {
            ui->Display->setItem(i+1,j+1,new QTableWidgetItem(QString::number(answer.value[i][j])));
        }
    }
    readTimer->start();
}


main

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

  • 10
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值