您好,欢迎访问代理记账网站
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

12.计算器核心解析算法(上)

计算机如何读懂四则运算表达式?

9.3+(3-0.11)中缀表达式,后缀表达式

5+3----5 3 +

1+2*3->1 2 3 * +

9 + (3 - 1 )*5 ->9 3 1 - 5 * +

 

中缀表达式符合人类的阅读和思维习惯

后缀表达式符合计算机的运算方式

解决方案

1.将中缀表达式进行数字和运算符的分离

将中缀表达式转换为后缀表达式

t哦那个过后缀表达式计算最终结果

数字和小数点【0-9或.】

符号位【—+】

运算符【——,-,*,/】

括号【或】

 

思想:以符号作为标志对表达式中字符访问

定义累计变量num

当前字符expi[i]为数字或小数点时:

累计:num += exp[i]

当前字符exp[i]为符号时:

num 为运算数,分离并保存

若exp[i]为正负号:

累计符号位+和=:num += exp[i]

或exp[i]为运算符:

分离并保存

for(int i = 0; i < exp.length(); i++)
{
if(exp[i])
累计:num+=exp[i]
else if(exp[i])//为符号
{
	if(num != "")
	分离并保存运算数:num;
	if(exp[i])//正号或负号
	符号位累计:num += exp[i]l
	else
	{
	分离并保存运算符:exp[i];
	}
}
}

难点:

如何区分正负号与加号和减号?

+和-在表达式的第一个位置

括号后的+和-

运算符号后的+和一

#include "QCalculatorDec.h"

QCalculatorDec::QCalculatorDec()
{
    m_exp = "";
    m_result = "";

    QQueue<QString> r = split("+9.11+(-3-1)*5");

    for(int i = 0; i < r.length(); i++)
    {
        qDebug() << r[i];
    }
}

QCalculatorDec::~QCalculatorDec()
{

}

bool QCalculatorDec::isDigitOrDot(QChar c)
{
    return (('0' <= c) && (c <= '9')) || (c == '.');
}

bool QCalculatorDec::isSymbol(QChar c)//操作符+ 0*
{
    return isOperator(c) || (c == '(') || (c == ')');
}

bool QCalculatorDec::isSign(QChar c)//是不是正负号
{
    return (c == '+') || (c == '-');
}

bool QCalculatorDec::isNumber(QString s)//合法的数字
{
    bool  ret = false;
    s.toDouble(&ret);
    return ret;
}

bool QCalculatorDec::isOperator(QString s)//四则运算符
{
    return (s == "+") || (s == "-") || (s == "*") || (s == "/");
}

bool QCalculatorDec::isLeft(QString s)
{
    return (s == "(");
}

bool QCalculatorDec::isRight(QString s)
{
    return (s == ")");
}

int QCalculatorDec::priority(QString s)//返回优先级
{
    int ret = 0;

    if((s == "+") || (s == "-"))
    {
        ret = 1;
    }

    if((s == "*") || (s =="/"))
    {
        ret = 2;
    }

    return ret;
}

QQueue<QString> QCalculatorDec::split(const QString& exp)//分离算法
{
    QQueue<QString> ret;
    QString num = "";
    QString pre = "";//保存前一个字符

    for(int i = 0; i < exp.length(); i++)
    {
        if(isDigitOrDot(exp[i]))
        {
            num += exp[i];
            pre = exp[i];
        }
        else if(isSymbol(exp[i]))//符号
        {
            if(!num.isEmpty())
            {
                ret.enqueue(num);
                num.clear();
            }

            if( isSign(exp[i]) && ( (pre == "") || (pre == "(") || isOperator(pre) ) )//正负号
            {
                num += exp[i];
            }
            else
            {
                ret.enqueue(exp[i]);
            }

            pre = exp[i];
        }
    }

    if( !num.isEmpty() )
    {
        ret.enqueue(num);
    }

    return ret;
}

小结:

QString 中每个字符为QChar

Qt中提供了开发中不可或缺的数据结构类

四则运算表达式的计算分三个步骤

数字和符号分离

中缀表达式转后缀表达式

根据后缀表达式计算结果


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进