zoukankan      html  css  js  c++  java
  • 智能语音计算器(二)

    这边文章来介绍该项目的计算引擎模块。

    #ifndef CALCULATORDEC_H
    #define CALCULATORDEC_H
    
    #include <qt5/QtCore/QString>
    #include <qt5/QtCore/QStack>
    #include <qt5/QtCore/QString>
    #include "ICalculator.h"
    
    class CalculatorDec : public ICalculator
    {
    public:
        CalculatorDec();
        ~CalculatorDec();
        bool expression(const QString & exp);
        QString result();
    
    private:
        QString calculate(const QString & exp);
        bool isDigit(char ch);
        bool isLeft(char ch);
        bool isDot(char ch);
        bool isRight(char ch);
        int judge(char c);
        double compute(char c,double a,double b);
    
    private:
        QString m_exp;
        QString m_result;
    };
    #endif
        bool expression(const QString & exp);
        QString result();
    这两个方法是重写 ICalculator中的方法,当然也可以通过别的方式实现,我在这是为了更好的理解Virtual函数的思想。
    下面是该类的具体实现
    #include "QCalculatorDec.h"
    
    CalculatorDec::CalculatorDec()
    {
        m_exp = "";
        m_result = "";
    }
    
    CalculatorDec::~CalculatorDec()
    {
    
    }
    
    bool CalculatorDec::expression(const QString & exp)
    {
        bool ret = false;
    
        m_result = calculate(exp);
        ret = (m_result != "Error");
    
        return ret;
    }
    
    QString CalculatorDec::result()
    {
        return m_result;
    }
    
    QString CalculatorDec::calculate(const QString & exp)
    {
        
        QString ret = "Error";
        QByteArray ba = exp.toLatin1();
        const char *str = ba.data();
        QStack<double> stack_digit;
        QStack<char> stack_op;
        const char *p;
        for(p=str;*p;p++)
        {
           
            if(isDigit(*p))
            {
                stack_digit.push(atof(p));
                while(isDigit(*p)) p++;
                if(isDot(*p))
                {
                    p=p+1;
                    while(isDigit(*p)) p++;
                }
                p--;
               // printf("%c
    ",*p);
            }
            else
            {
                if(stack_op.isEmpty() || isLeft(*p))
                {
                    stack_op.push(*p);
                    continue;
                }
                else
                {
                    if(isRight(*p))
                    {
                        while(!isLeft(stack_op.top()))
                        {
                            char b1 = stack_op.pop();
                            double a1 = stack_digit.pop();
                            double a2 = stack_digit.pop();
                            stack_digit.push(compute(b1,a1,a2));
                        }
                        stack_op.pop();
                    }
                    else
                    {
                        if(!isLeft(stack_op.top()))
                        {
                            if(judge(*p)<=judge(stack_op.top()))
                            {
                                char b2 = stack_op.pop();
                                double a3 = stack_digit.pop();
                                double a4 = stack_digit.pop();
                                stack_digit.push(compute(b2,a3,a4));
                                p--;
                                continue;
                            }
                            else
                            {
                                stack_op.push(*p);
                            }
                        }
                        else
                        {
                            stack_op.push(*p);
                        }
                    }
                }
            }
        }
        while(!stack_op.isEmpty())
        {
            char b3 = stack_op.pop();
            double a5 = stack_digit.pop();
            double a6 = stack_digit.pop();
            stack_digit.push(compute(b3,a5,a6));
        }
        double ret1 = stack_digit.pop();
        ret = QString::number(ret1,'f',2);
        return ret;
    }
    
    bool CalculatorDec::isDigit(char ch)
    {
        if(ch>='0' && ch<='9')  return true;
        else return false;
    }
    
    bool CalculatorDec::isLeft(char ch)
    {
        if(ch=='(') return true;
        else return false;
    }
    
    bool CalculatorDec::isDot(char ch)
    {
        if(ch=='.')   return true;
        else return false;
    }
    
    bool CalculatorDec::isRight(char ch)
    {
        if(ch==')') return true;
        else return false;
    }
    
    int CalculatorDec::judge(char c)
    {
        int ret = 0;
        if(c=='+' || c=='-')
            ret = -1;
        if(c=='*' || c=='/')
            ret = 0;
        return ret;
    }
    
    double CalculatorDec::compute(char c,double a,double b)
    {
        double ret = 0;
        if(c=='+')  ret = b+a;
        if(c=='-')  ret = b-a;
        if(c=='*')  ret = b*a;
        if(c=='/')  ret = b/a;
        return ret;
    }

    说一下算法设计思路,首先是用两个栈来存放数据和符号(数据栈和符号栈)。

    算法(重点):

    数字:数字无条件入栈
    符号:
    判断符号栈是否为空,如果为空,则无条件入栈
    如果不为空,

    当前符号如果为右括号:
    一直去弹符号栈,直到弹出第一个左括号。

    当前符号如果不为右括号: 
    判读栈顶元素是不是左括号
    栈顶不是左括号 
    当前符号优先级 <= 栈顶元素的优先级,则计算。(出栈一个符号,出两个数字,先出栈的数字是右操作数,后出栈的数字是左操作数)
    当前符号优先级 > 栈顶元素的优先级,符号入栈。

    栈顶是左括号
    当前符号无条件入栈

    循环结束:
    判断符号栈是否为空,如果为空,则数据栈的栈顶元素,就是最后的结果。
    如果不空,一直计算,直到符号栈为空。

  • 相关阅读:
    python修改python unittest的运行顺序
    史上最强大的python selenium webdriver的包装
    第六种方式,python使用cached_property缓存装饰器和自定义cached_class_property装饰器,动态添加类属性(三),selnium webdriver类无限实例化控制成单浏览器。
    python带参装饰器的改良版
    第五种方式,python使用组合来添加类方法和属性(二),以selenium的webdriver为例
    python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)
    linux添加PYTHONPATH环境变量
    linux 按照端口一句命令杀死进程,按照进程名称一句命令杀死进程
    python __all__用法
    使用pycharm,追求最优的代码。
  • 原文地址:https://www.cnblogs.com/wzqstudy/p/10076610.html
Copyright © 2011-2022 走看看