关于字符串四则运算表达式的求解,网上有很多利用变字符串为前缀表达式或后缀表达式实验的方法,本人觉得模拟笔算的方法简单易懂,这里给出了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);
}