From 6acdb21e2d97dba5bf76117c8eab0abf0ce4a9e5 Mon Sep 17 00:00:00 2001 From: iridiumR Date: Tue, 29 Mar 2022 16:42:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A6=82=E6=AD=A4=E7=BE=8E=E5=A6=99=E7=9A=84?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Code/2-2-5_enhanced/2-2-5_enhanced.pro | 26 +++ SoftwareDesign/Code/2-2-5_enhanced/cal.cpp | 75 ++++++++ SoftwareDesign/Code/2-2-5_enhanced/cal.h | 5 + SoftwareDesign/Code/2-2-5_enhanced/main.cpp | 11 ++ .../Code/2-2-5_enhanced/mainwindow.cpp | 94 ++++++++++ .../Code/2-2-5_enhanced/mainwindow.h | 51 +++++ .../Code/2-2-5_enhanced/mainwindow.ui | 177 ++++++++++++++++++ 7 files changed, 439 insertions(+) create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/2-2-5_enhanced.pro create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/cal.cpp create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/cal.h create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/main.cpp create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/mainwindow.cpp create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/mainwindow.h create mode 100644 SoftwareDesign/Code/2-2-5_enhanced/mainwindow.ui diff --git a/SoftwareDesign/Code/2-2-5_enhanced/2-2-5_enhanced.pro b/SoftwareDesign/Code/2-2-5_enhanced/2-2-5_enhanced.pro new file mode 100644 index 0000000..bc0f036 --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/2-2-5_enhanced.pro @@ -0,0 +1,26 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + cal.cpp \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + cal.h \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/SoftwareDesign/Code/2-2-5_enhanced/cal.cpp b/SoftwareDesign/Code/2-2-5_enhanced/cal.cpp new file mode 100644 index 0000000..9b02528 --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/cal.cpp @@ -0,0 +1,75 @@ +#include // remove() +#include // pow() +#include +#include // stack +#include // runtime_error +#include // string +using std::string; + +// 返回运算符的优先级,值越大,优先级越高 +inline size_t precedence(const char op) { + if (op == '+' || op == '-') + return 1; + if (op == '*' || op == '/') + return 2; + if (op == '^') + return 3; + throw std::runtime_error{string{"表达中包含无效的运算符"} + op}; +} +// 计算 +double execute(std::stack &ops, std::stack &operands) { + double result{}; + double rhs{operands.top()}; // 得到右操作数 + operands.pop(); + double lhs{operands.top()}; // 得到做操作数 + operands.pop(); + switch (ops.top()) // 根据两个操作数之间的运算符,执行相应计算 + { + case '+': + result = lhs + rhs; + break; + case '-': + result = lhs - rhs; + break; + case '*': + result = lhs * rhs; + break; + case '/': + result = lhs / rhs; + break; + case '^': + result = std::pow(lhs, rhs); + break; + default: + throw std::runtime_error{string{"invalid operator: "} + ops.top()}; + } + ops.pop(); //计算完成后,该运算符要弹栈 + operands.push(result); //将新计算出来的结果入栈 + return result; +} +double cal(string exp) { + static std::stack operands; //存储表达式中的运算符 + static std::stack operators; //存储表达式中的数值 + //移除用户输入表达式中包含的无用的空格 + size_t index{}; + //每个表达式必须以数字开头,index表示该数字的位数 + operands.push(std::stod(exp, &index)); // 将表达式中第一个数字进栈 + while (true) { + operators.push(exp[index++]); // 将运算符进栈 + size_t i{}; + operands.push( + std::stod(exp.substr(index), + &i)); //将运算符后的数字也进栈,并将数字的位数赋值给 i。 + index += i; //更新 index + if (index == exp.length()) { + while (!operators.empty()) //如果 operators不为空,表示还没有计算完 + execute(operators, operands); + break; + } + //如果表达式还未遍历完,但子表达式中的运算符优先级比其后面的运算符优先级大,就先计算当前的子表达式的值 + while (!operators.empty() && + precedence(exp[index]) <= precedence(operators.top())) + execute(operators, operands); + } + return operands.top(); +} diff --git a/SoftwareDesign/Code/2-2-5_enhanced/cal.h b/SoftwareDesign/Code/2-2-5_enhanced/cal.h new file mode 100644 index 0000000..06dde1d --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/cal.h @@ -0,0 +1,5 @@ +#ifndef CAL_H +#define CAL_H +#include +double cal(std::string exp); +#endif // CAL_H diff --git a/SoftwareDesign/Code/2-2-5_enhanced/main.cpp b/SoftwareDesign/Code/2-2-5_enhanced/main.cpp new file mode 100644 index 0000000..fd3e533 --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.cpp b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.cpp new file mode 100644 index 0000000..4ae1ea6 --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.cpp @@ -0,0 +1,94 @@ +#include "mainwindow.h" +#include "cal.h" +#include "ui_mainwindow.h" +#include + +static QString displayText; + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui(new Ui::MainWindow) { + ui->setupUi(this); + ui->lineEdit->setText("0"); + result = 0.0; + waitForOperand = true; + + connectSlots(); +} + +MainWindow::~MainWindow() { delete ui; } + +//错误处理 +void MainWindow::abortOperation() { + result = 0.0; + pendingOperator.clear(); + ui->lineEdit->setText("0"); + waitForOperand = true; + QMessageBox::warning(this, "运算错误", "除数不能为零"); +} + +//数字被点击 +void MainWindow::digitClicked() { + QPushButton *digitBtn = static_cast(sender()); + // if(ui->lineEdit->text() == "0" && value == "0") + // return; + if (!isFinished) { + displayText.append(digitBtn->text()); + ui->lineEdit->setText(displayText); + } else { + return; + } +} + +void MainWindow::on_clearBtn_clicked() { + //将当前显示的数归零 + displayText.chop(1); + ui->lineEdit->setText(displayText); + isFinished = false; +} + +void MainWindow::on_clearAllBtn_clicked() { + //将当前显示的数据归零,并将之前保存的数据运算清除 + displayText.clear(); + ui->lineEdit->setText(displayText); + isFinished = false; + result = 0.0; +} + +void MainWindow::on_equalBtn_clicked() { + result = cal(displayText.toStdString()); + isFinished = 1; + ui->lineEdit->setText(QString::number(result)); +} + +//运算符 +void MainWindow::operatorClicked() { + QPushButton *clickedBtn = qobject_cast(sender()); + if (!isFinished) { + displayText.append(clickedBtn->text()); + ui->lineEdit->setText(displayText); + } else { + return; + } +} + +//槽链接 +void MainWindow::connectSlots() { + + QPushButton *digitBtns[10] = {ui->digitBtn0, ui->digitBtn1, ui->digitBtn2, + ui->digitBtn3, ui->digitBtn4, ui->digitBtn5, + ui->digitBtn6, ui->digitBtn7, ui->digitBtn8, + ui->digitBtn9}; + for (auto btn : digitBtns) + connect(btn, &QPushButton::clicked, this, &MainWindow::digitClicked); + QPushButton *operatorBtns[6] = {ui->addBtn, ui->subtractionBtn, + ui->mulBtn, ui->divisionBtn, + ui->squareBtn, ui->pointBtn}; + for (auto btn : operatorBtns) + connect(btn, &QPushButton::clicked, this, &MainWindow::operatorClicked); +} + +//没用的函数,让它能编译成功 + +void MainWindow::on_squareBtn_clicked() {} +void MainWindow::on_pointBtn_clicked() {} +void MainWindow::on_signBtn_clicked() {} diff --git a/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.h b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.h new file mode 100644 index 0000000..2d5262b --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.h @@ -0,0 +1,51 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow *ui; + + //终止运算,清除数据,报错 + void abortOperation(); + //连接信号和槽 + void connectSlots(); + //储存运算符 + QString pendingOperator; + //储存运算结果 + double result; + //标记是否等待一个操作数 + bool waitForOperand; + + bool isFinished; + +private slots: + void on_clearBtn_clicked(); + + void on_clearAllBtn_clicked(); + + void on_equalBtn_clicked(); + + void digitClicked(); + + void on_signBtn_clicked(); + + void operatorClicked(); + + void on_pointBtn_clicked(); + + void on_squareBtn_clicked(); +}; +#endif // MAINWINDOW_H diff --git a/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.ui b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.ui new file mode 100644 index 0000000..8c05681 --- /dev/null +++ b/SoftwareDesign/Code/2-2-5_enhanced/mainwindow.ui @@ -0,0 +1,177 @@ + + + MainWindow + + + + 0 + 0 + 405 + 320 + + + + Calculator_v2_4490 + + + + + + + 5 + + + + + + + / + + + + + + + 3 + + + + + + + 4 + + + + + + + * + + + + + + + 2 + + + + + + + Clear + + + + + + + ClearAll + + + + + + + . + + + + + + + 0 + + + + + + + = + + + + + + + 1 + + + + + + + 6 + + + + + + + - + + + + + + + 7 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + 8 + + + + + + + 9 + + + + + + + + + + + + + + + ^ + + + + + + + + + 0 + 0 + 405 + 30 + + + + + + + +