• 表达式计算器类的设计2(表达式计算器5)


    计算器的github下载地址:https://github.com/ljian1992/calculator

    符号表,函数表,变量存储表

    表达式计算器,需要支持变量和函数,而变量和函数都是些符号,因此设置一个SymbolTable类来存储这些符号。符号有两种,一种是变量,一种是函数,故在设置一个Storage类存储变量中的值,设置一个FunctionTable类来存储函数。由于这三中类存在着联系,现在在设置一个Calc类来管理它们。

     

    SymbolTable类,FunctionTable类,Storage类,Calc类的关系

    根据符号表中的符号对应的的ID,在Storage中根据ID找到变量的值,或者是在FunctionTable中根据ID找到相对应得数学函数

    image

     

    SymbolTable类,FunctionTable类,Storage类,Calc类的设计

    SymbolTable类
    class SymbolTable : public Serializable
    {
    private:
        std::map<const std::string, unsigned int> dictionary_;  //存储符号与id相对应得关系
        unsigned int curId_;                                    //存储将要加入符号表的符号id
    public:
        enum { IDNOTFOUND = 0xFFFFFFFF };                       //IDNOTFOUND代表在符号表中找不到相应的符号
        SymbolTable() : curId_(0) {}                            
        unsigned int Add(const std::string& str);               //向符号表中加入符号
        unsigned int Find(const std::string& str) const;        //根据符号寻找符号表中是否存储该符号
        unsigned int GetCurId()const;                           //获取下一个的加入符号表的符号id
        void Clear();                                           //清楚符号表
        const std::string &GetSymbolName(unsigned int id) const;//根据id查找并获取符号表中的符号
      virtual void Serialize(Serializer& out) const;          //文件存储
        virtual void DeSerialize(DeSerializer& in);             //文件加载
    };    Storage类
    class Storage : public Serializable
    {
    private:
        std::map<unsigned int, double> cells_;        //存储符号表中id与值多对应的关系
      public:
        Storage(SymbolTable& tbl);
        void Clear();                                 //清除数据
        void AddConstants(SymbolTable& tbl);          //增加常量,目前只支持pi e
        double GetValue(unsigned int id) const;       //根据id获得想对于的值
        unsigned int GetSize() const;                 //获取map中有多少个数据
        void SetValue(unsigned int id, double val);   //设置map中的值
        void AddValue(unsigned int id, double val);   //想map中添加值
        
        virtual void Serialize(Serializer& out) const;//将Storage类中的值存入文件存储
        virtual void DeSerialize(DeSerializer& in);   //将文件中的值加载到Storage类中
    };
    
    
    
    FunctionTable类   typedef double(*PtrFun)(double);                 //重命名了一种函数指针类
      class FunctionTable
    {
    private:                
        std::map<unsigned int, PtrFun> funsMap_;     //存储符号表中的id与对应的数学函数指针
    public:
        FunctionTable(SymbolTable& tbl);
        void Init(SymbolTable& tbl);                 //存储是函数表
        PtrFun GetFunction(unsigned int id) const;   //根据id获取函数表中对应的函数
        unsigned int GetSize() const;                //获得函数表中有多少个函数
       ~FunctionTable();   };
    
    
    Calc类
    class Calc : public Serializable
    {
        friend class Parser;          //使到Parser类方便的访问Calc的私有成员
    private:
        //由于Storage的构造函数需要用到SymbolTable的引用,故声明顺序SymbolTable在Storage的前面
        SymbolTable symTbl_;  
        FunctionTable functionTbl_;   //由于函数表中的函数是固定的,因此把函数表的构造放在符号表的前面
        Storage storage_;             //变量的个数是不固定的
        unsigned int FindSymbol(const std::string& str) const;  //在符号表中查找str符号
        unsigned int AddSymbol(const std::string& str);         //往符号表中添加符号
        Storage& GetStorage();                                  //获取stroage_的引用
        bool IsFunction(unsigned int id) const;                 //判断是否是函数
        PtrFun GetFunction(unsigned int id) const;              //获取函数指针
        double GetVariableValue(unsigned int id) const;         //获取变量的值
    public:
        Calc() : symTbl_(), functionTbl_(symTbl_), storage_(symTbl_) {}
        void ListFun() const;                                   //打印函数表
        void ListVariable() const;                              //打印变量表
      virtual void Serialize(Serializer& out) const;          //将函数表和变量表中的内容存储到文件中
        virtual void DeSerialize(DeSerializer& in);             //从文件中加载内容到符号表和变量表中
      };
  • 相关阅读:
    关于一个标准的poi下载文件模板 可拿来来直接使用
    关于史上最简单的导出(导出excal)
    关于spring MVC的面试题
    关于响应式布局(pc端访问自适应 手机端访问自适应)
    密码生成器
    关于poi的导出(POI)
    关于MUI一个很实用的前端框架
    (转载)插画版Kubernetes指南(小孩子也能看懂的kubernetes教程)
    (转载)Python tips: 什么是*args和**kwargs?
    python编程中的if __name__ == 'main': 的作用和原理
  • 原文地址:https://www.cnblogs.com/Ljian1992/p/4287157.html
Copyright © 2020-2023  润新知