.h文件:
//返回值 1---表达式正确 0---表达式错误 -1---不是合格的表达式 否则为正常运算符的结果
static double parseExpressionString(QString exp);
//逻辑运算符计算
static void calucationLogic(QStringList &values,QStringList &exps,QString method);
.cpp文件:
/***
*判断一个字符串是否为纯数字
*/
int isDigitStr(QString src)
{
QByteArray ba = src.toLatin1();//QString 转换为 char*
const char *s = ba.data();
while(*s && *s>='0' && *s<='9') s++;
if (*s)
{ //不是纯数字
return -1;
}
else
{ //纯数字
return 0;
}
}
// + - * / && || ( ) == >= <= != > <
double ExpressionFunc::parseExpressionString(QString exp)
{
QStringList symbols;
symbols<<"+"<<"-"<<"*"<<"/"<<"&"<<"|"<<"="<<">"<<"<"<<"!";
//去除空格
exp = exp.replace(" ","");
QStringList values;//值
QStringList exps;//运算符
QString tempStr;
for(int i=0;i
QString str = exp.mid(i,1);
//判读是不是运算符
if(str == ")"){
//肯定得是先找到 (
return -1;
}
if(str == "("){
if(tempStr.length() > 0){
values.push_back(tempStr);
tempStr = "";
}
//找最外层的右括号
int index = 0;
while (exp.indexOf(")",index) != -1) {
index = exp.indexOf(")",index);
++index;
}
if(index == -1 && index < i){
return -1;
}
index--;
double result = parseExpressionString(exp.mid(i+1,index-i-1));
if(result < 0){
return -1;
}
values.push_back(QString::number(result));
i = index+1;
}else if (symbols.contains(str)) {
if(tempStr.length() > 0){
values.push_back(tempStr);
tempStr = "";
}
if(str==">" || str=="<" || str=="=" || str=="!"){
//判断下一个
if(i == exp.count()-1){
return -1;
}
QString nextStr = exp.mid(i+1,1);
if(nextStr == "="){
//大于等于
exps.push_back(str + nextStr);
i++;
}else {
if(str == "!") return -1;
exps.push_back(str);
}
}else if (str=="&" || str=="|") {
//与 -- 或
//判断下一个
if(i == exp.count()-1){
return -1;
}
QString nextStr = exp.mid(i+1,1);
if(nextStr == str){
exps.push_back(str + nextStr);
i++;
}else {
exps.push_back(str);
}
}else {
exps.push_back(str);
}
}else if (str == ".") {
//小数点
if(tempStr.contains(".")){
//不能同时存在两个小数点
return -1;
}
tempStr = tempStr.append(str);
}else {
//判读是否是有效数字
int result = isDigitStr(str);
if(result < 0){
return -1;
}
tempStr = tempStr.append(str);
}
}
if(tempStr.length() > 0){
values.append(tempStr);
}
//这里就得到了正确一个值加运算符的两个数组 第一个肯定是值且必须有两个值 值-运算符-值-运算符
if(values.count() <= 1) return -1;
if(values.count() != exps.count() + 1) return -1;
while (exps.contains("*") || exps.contains("/")) {
int multiIndex = exps.indexOf("*");
int divIndex = exps.indexOf("/");
//先算乘法还是先算除法
if(multiIndex >= 0 && divIndex >= 0){
if(multiIndex < divIndex){
//先算乘法
double left = values.at(multiIndex).toDouble();
double right = values.at(multiIndex + 1).toDouble();
double result = left*right;
values.replace(multiIndex,QString::number(result));
values.removeAt(multiIndex + 1);
exps.removeAt(multiIndex);
}else {
//先算除法
double left = values.at(divIndex).toDouble();
double right = values.at(divIndex + 1).toDouble();
double result = left/right;
values.replace(divIndex,QString::number(result));
values.removeAt(divIndex + 1);
exps.removeAt(divIndex);
}
}else if (multiIndex >= 0 && divIndex < 0) {
//只有乘法
double left = values.at(multiIndex).toDouble();
double right = values.at(multiIndex + 1).toDouble();
double result = left*right;
values.replace(multiIndex,QString::number(result));
values.removeAt(multiIndex + 1);
exps.removeAt(multiIndex);
}else if (multiIndex < 0 && divIndex >= 0) {
//只有除法
double left = values.at(divIndex).toDouble();
double right = values.at(divIndex + 1).toDouble();
double result = left*right;
values.replace(divIndex,QString::number(result));
values.removeAt(divIndex + 1);
exps.removeAt(divIndex);
}
}
//再算加减
while (exps.contains("+") || exps.contains("-")) {
int addIndex = exps.indexOf("+");
int reduceIndex = exps.indexOf("-");
if(reduceIndex >= 0 && addIndex >= 0){
if(addIndex < reduceIndex){
//先加
double left = values.at(addIndex).toDouble();
double right = values.at(addIndex + 1).toDouble();
double result = left+right;
values.replace(addIndex,QString::number(result));
values.removeAt(addIndex + 1);
exps.removeAt(addIndex);
}else {
double left = values.at(reduceIndex).toDouble();
double right = values.at(reduceIndex + 1).toDouble();
double result = left+right;
values.replace(reduceIndex,QString::number(result));
values.removeAt(reduceIndex + 1);
exps.removeAt(reduceIndex);
}
}else if(addIndex >= 0){
double left = values.at(addIndex).toDouble();
double right = values.at(addIndex + 1).toDouble();
double result = left+right;
values.replace(addIndex,QString::number(result));
values.removeAt(addIndex + 1);
exps.removeAt(addIndex);
}else if (reduceIndex >= 0) {
double left = values.at(reduceIndex).toDouble();
double right = values.at(reduceIndex + 1).toDouble();
double result = left+right;
values.replace(reduceIndex,QString::number(result));
values.removeAt(reduceIndex + 1);
exps.removeAt(reduceIndex);
}
}
if(values.count() == 1 && exps.count()==0){
return values.first().toDouble();
}
//到这里就只有逻辑运算符了 '>' '<' '>=' '<=' '==' '!=' '&&' '||'
QStringList tempList;
tempList<<">"<<"<"<<">="<<"<="<<"=="<<"!=";
for(int i=0;i
calucationLogic(values,exps,tempList.at(i));
}
if(values.count() == 1 && exps.count()==0){
return values.first().toDouble()> 0?1:0;
}
//到这里就只有 '&&' '||'
while (exps.contains("&&") || exps.contains("||")) {
int andIndex = exps.indexOf("&&");
int orIndex = exps.indexOf("||");
if(andIndex >=0 && orIndex >= 0){
if(andIndex < orIndex){
double left = values.at(andIndex).toDouble();
double right = values.at(andIndex + 1).toDouble();
double result = left&&right?1:0;
values.replace(andIndex,QString::number(result));
values.removeAt(andIndex + 1);
exps.removeAt(andIndex);
}else {
double left = values.at(orIndex).toDouble();
double right = values.at(orIndex + 1).toDouble();
double result = left||right?1:0;
values.replace(orIndex,QString::number(result));
values.removeAt(orIndex + 1);
exps.removeAt(orIndex);
}
}else if (andIndex >= 0) {
double left = values.at(andIndex).toDouble();
double right = values.at(andIndex + 1).toDouble();
double result = left&&right?1:0;
values.replace(andIndex,QString::number(result));
values.removeAt(andIndex + 1);
exps.removeAt(andIndex);
}else if (orIndex >= 0) {
double left = values.at(orIndex).toDouble();
double right = values.at(orIndex + 1).toDouble();
double result = left||right?1:0;
values.replace(orIndex,QString::number(result));
values.removeAt(orIndex + 1);
exps.removeAt(orIndex);
}
}
if(values.count() == 1 && exps.count()==0){
return values.first().toDouble() > 0?1:0;
}
return -1;
}
void ExpressionFunc::calucationLogic(QStringList &values, QStringList &exps,QString method)
{
while (exps.contains(method)) {
int loc = exps.indexOf(method);
double left = values.at(loc).toDouble();
double right = values.at(loc + 1).toDouble();
int result;
if(method==">"){
result = left>right?1:0;
}else if(method=="<"){
result = left
}else if(method==">="){
result = left>=right?1:0;
}else if(method=="<="){
result = left<=right?1:0;
}else if(method=="=="){
result = left==right?1:0;
}else if(method=="!="){
result = left!=right?1:0;
}
values.replace(loc,QString::number(result));
values.removeAt(loc + 1);
exps.removeAt(loc);
}
}
调用示例
double result = ExpressionFunc::parseExpressionString("10>9&&(5>2*4)");
result : -1 不是合格的表达式、0 表达式返回false、 1 表达式返回true
网友评论