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();
}