字符串四则运算表达式的求解(中缀表达式实现,模拟笔算的方法)

    关于字符串四则运算表达式的求解,网上有很多利用变字符串为前缀表达式或后缀表达式实验的方法,本人觉得模拟笔算的方法简单易懂,这里给出了QT的具体实现,未经大量测试,仅供参考。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QQueue>
#include <QStack>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void parseStringToStack(QStack<double> &q = stact_num, const QString &s = input);
    void parseSymbolToStack(QStack<QChar> &q = stact_smb, QString &s = input);
    int findTheLastNonNum(const QString &s, int pos);
    double calc(QStack<double> &stact_n, QStack<QChar> &stact_s);
    double calccc(QStack<double> sd, QStack<QChar> ss);

private slots:
    void on_pushButton_clicked();

    void on_lineEdit_num_returnPressed();

    void on_lineEdit_num_textChanged(const QString &arg1);

    void on_pushButton_reset_clicked();

    void on_textEdit_input_textChanged();

private:
    Ui::MainWindow *ui;
    QString static input;
    QStack<double> static stact_num;
    QStack<QChar> static stact_smb;
};

#endif // MAINWINDOW_H

mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

QString MainWindow::input;
QStack<double> MainWindow::stact_num;
QStack<QChar> MainWindow::stact_smb;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    input = "";
    ui->lineEdit_num->setStyleSheet("font-size : 26px");
    ui->lineEdit_result->setStyleSheet("font-size : 24px");
    ui->textEdit_input->setStyleSheet("font-size : 24px");
    QObject::connect(ui->lineEdit_num, SIGNAL(returnPressed()), this, SLOT(on_pushButton_clicked()));
}

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

double MainWindow::calc(QStack<double> &stact_n, QStack<QChar> &stact_s)
{
    double result = 0;
    while(!stact_s.isEmpty())
    {
        QStack<double> stack_num1;
        QStack<QChar> stack_smb1;
        double cc;
        QChar ch = stact_s.pop();
        switch (ch.toLatin1()) {
        case '+':
            result += stact_n.pop();
            break;
        case '-':
            result -= stact_n.pop();
            break;
        case '*':
        case '/':
            stack_smb1.push(ch);
            stack_num1.push(stact_n.pop());
            while(!stact_s.isEmpty())
            {
                ch = stact_s.pop();
                if(!(ch == '*' || ch == '/'))
                {
                    stact_s.push(ch);
                    break;
                }
                stack_smb1.push(ch);
                stack_num1.push(stact_n.pop());
            }
            stack_num1.push(stact_n.pop());
            cc = calccc(stack_num1, stack_smb1);
            //QMessageBox::warning(this, "cc", QString::number(cc));
            stact_n.push(cc);
            break;
        default:
            break;
        }
    }
    if(!stact_n.isEmpty())
        result += stact_n.pop();
    return result;
}

void MainWindow::on_pushButton_clicked()
{
    QString num = ui->lineEdit_num->text();
    if("" != num)
    {
        QString str = num.mid(0, num.length());
        bool ok = false;
        str.toDouble(&ok);
        if(!ok)
        {
            QMessageBox::warning(this, "输入警告", "输入值错误!");
            return;
        }
        str = ui->textEdit_input->toPlainText();
        str += num;
        ui->textEdit_input->setText(str);
        ui->lineEdit_num->clear();
    }

    input = ui->textEdit_input->toPlainText();
    if("" == input)
        return;

    int pos1 = input.lastIndexOf('(');
    int pos2 = input.indexOf(')', pos1);
    while(pos1 != -1)
    {
        QString str = input.mid(pos1+1, pos2-pos1-1);
        input.remove(pos1, pos2 - pos1 + 1);

        parseStringToStack(stact_num, str);

        double val;

        if(stact_num.isEmpty())
        {
            QMessageBox::warning(this, "输入警告", "输入的()内为空!");
            exit(0);
        }
        if(stact_num.length()==1)
        {
            val = stact_num.pop();
            input.insert(pos1, QString::number(val));
            continue;
        }

        if(stact_num.length() != stact_smb.length() + 1)
        {
            QMessageBox::warning(this, "输入警告", "输入的()有误!");
        }

        val = calc(stact_num, stact_smb);

        input.insert(pos1, QString::number(val));
        //3+4*(3-(2*3))-2*(1+2)
        QMessageBox::warning(this, "输入警告", input);

        /*QString sisi = "+13.14";
        double xixi = sisi.toDouble();
        QMessageBox::warning(this, "ceshi", QString::number(xixi));*/

        pos1 = input.lastIndexOf('(');
        pos2 = input.indexOf(')', pos1);
    }

    parseStringToStack();
    if(stact_num.isEmpty())
    {
        ui->lineEdit_result->clear();
        return;
    }
    if(stact_num.length()==1)
    {
        ui->lineEdit_result->setText(QString::number(stact_num.pop()));
        return;
    }

    double result = calc(stact_num, stact_smb);

    ui->lineEdit_result->setText(QString::number(result));
}

double MainWindow::calccc(QStack<double> sd, QStack<QChar> ss)
{
    double z = sd.pop();
    while(!ss.isEmpty())
    {
        QChar ch = ss.pop();
        switch (ch.toLatin1())
        {
            case '*':
                z *= sd.pop();
                break;
            case '/':
                z /= sd.pop();
                break;
            default:
                break;
        }
    }
    return z;
}

void MainWindow::on_lineEdit_num_returnPressed()
{

}

void MainWindow::on_lineEdit_num_textChanged(const QString &arg1)
{
    QString num = ui->lineEdit_num->text();
    if(num=="")
        return;
    int len = num.length();
    QChar ch = num[len-1];
    if(ch == 'r' || ch == 'R')
    {
        ui->lineEdit_num->clear();
        ui->lineEdit_result->clear();
        return;
    }
    if(ch == 'c' || ch == 'C')
    {
        input.clear();
        ui->lineEdit_num->clear();
        ui->lineEdit_result->clear();
        ui->textEdit_input->clear();
        return;
    }
    if((ch>='0' && ch<='9') || (ch=='.'))
    {
        return;
    }
    else if(ch=='+' || ch=='-' || ch=='*' || ch=='/')
    {
        int len = num.length();
        if(len > 1)
        {
            QString str = num.mid(0, len-1);
            bool ok = false;
            str.toDouble(&ok);
            if(!ok)
            {
                QMessageBox::warning(this, "输入警告", "输入值错误!");
                return;
            }
        }
        input += num;
        ui->textEdit_input->setText(input);
        ui->lineEdit_num->clear();
    }
    else
    {
        QMessageBox::warning(this, "输入警告", "输入值错误!");
    }
}

void MainWindow::on_pushButton_reset_clicked()
{
    input.clear();
    ui->lineEdit_num->clear();
    ui->lineEdit_result->clear();
    ui->textEdit_input->clear();
}

int MainWindow::findTheLastNonNum(const QString &s, int pos)
{
    if(s.length() - 1 < pos)
        return -1;
    for(int i = pos; i > 0; i--)
    {
        if(s[i]=='+' || s[i]=='-' || s[i]=='*' || s[i]=='/')
        {
            if(i>0 && (s[i-1]=='*' || s[i-1]=='/'))
            {
                i--;
            }
            return i;
        }
    }
    return -1;
}

void MainWindow::parseStringToStack(QStack<double> & q, const QString & s)
{
    stact_num.clear();
    stact_smb.clear();
    if(s == "")
    {
        q.clear();
        return;
    }
    s.trimmed();
    int len = s.length();
    int pos = len - 1;
    if(s[len-1] == '.' || s[len-1]=='+' || s[len-1]=='-' || s[len-1]=='*' || s[len-1]=='/')
    {
        if(len == 1)
        {
            q.clear();
            this->ui->lineEdit_num->clear();
            this->ui->lineEdit_result->clear();
            this->ui->textEdit_input->clear();
            return;
        }
        pos--;
    }
    QString tmp;
    int pos1;
    while(1)
    {
        pos1 = this->findTheLastNonNum(s, pos);
        if(pos1 == -1)
        {
            tmp = s.mid(0, pos+1);
            stact_num.push_front(tmp.toDouble());
            return;
        }
        else {
            tmp = s.mid(pos1+1, pos-pos1);
            stact_num.push_front(tmp.toDouble());
            stact_smb.push_front(s[pos1]);
            pos = pos1 - 1;
        }
    }
}

void MainWindow::on_textEdit_input_textChanged()
{
    ui->lineEdit_result->clear();
    QTextCursor cursor = ui->textEdit_input->textCursor();
    cursor.movePosition(QTextCursor::End);
    ui->textEdit_input->setTextCursor(cursor);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值