首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >行为型之解释器模式C++实现

行为型之解释器模式C++实现

作者头像
用户9831583
发布于 2022-06-16 15:51:01
发布于 2022-06-16 15:51:01
6760
举报
文章被收录于专栏:码出名企路码出名企路

现实需求:有些问题多次重复出现,而且有一定的相似性和规律性。

解释器模式:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。

优点:

  1. 扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
  2. 容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

缺点:

  1. 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。

2. 可应用的场景比较少。

主要角色。

  1. 抽象表达式角色:定义解释器的接口,约定解释器的解释操作。
  2. 终结符表达式角色:抽象表达式的子类,实现文法中与终结符相关的操作。
  3. 非终结符表达式角色:抽象表达式的子类,实现文法中与非终结符相关的操作。
  4. 环境角色:包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  5. 客户端:用解释器的解释方法,通过环境角色间接访问解释器的解释方法。

具体案例:小码路接了公司一项目,为北大清华的学生制作出入证,先找到学校学生可以进步,如果找不到侧拒绝进入校园。

第一步:抽象表达式

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <set>
#include <unordered_set>
#include <numeric>
#include <vector>
using namespace std;

//抽象表达式
class Expression
{
    public:
        virtual bool interpret(string mess)=0;
};

第二步:终结符表达式

代码语言:javascript
复制
//终结符表达式
class TerminalExpression:public Expression
{
    public:
        TerminalExpression(vector<string> info)
        {
            for(int i=0;i<info.size();i++)
            {
                _set.insert(info[i]);
                cout<<_set.size()<<endl;
            }      
        }
        bool interpret(string mess)//3
        {  
            std:;unordered_set<std::string>::const_iterator pos1;
            for (pos1 = _set.begin();pos1 != _set.end();)
            {
                cout<<"pos1: "<<*pos1<<endl;
                ++pos1;
            }

            std::unordered_set<std::string>::const_iterator got = _set.find(mess);
            if(got == _set.end())
            {  
                cout<<"查无此人 或 学校"<<endl;
                return false;
            }
              
            else
            {
                cout<<" 找到了 "<< *got<<endl;
                 return true;
            }
        }
    private:
        unordered_set<string> _set;
};

第三步:非终结符表达式

代码语言:javascript
复制
//非终结符表达式
class AndExpression : public Expression
{
    public:
        AndExpression(Expression *school,Expression *student)
        {
            this->school= school;
            this->student= student;
        }

        vector<string> split(string s,string seprate)
        {
            vector<string> ret;
            int seprate_len=seprate.length();
            int start=0;
            int index;
            while((index = s.find(seprate,start))!=-1){
                ret.push_back(s.substr(start,index-start));
                start = index+seprate_len;
            }
            if(start<s.length())
                ret.push_back(s.substr(start,s.length()-start));
            return ret;
        }

        bool interpret(string mess)//2
        {
            cout<< "mess"<< mess <<endl;
            vector<string> s=split(mess,"的");
            cout<<"000: "<<s.size()<<endl;
            cout<<"s[0]: "<<s[0]<<" s[1]: "<<s[1]<<endl;
            return school->interpret(s[0]) && student->interpret(s[1]);
        }
    
    private:
        Expression *school;
        Expression *student;
};

第四步:环境类

代码语言:javascript
复制
//环境类
class Context
{
    public:
        Context()
        {
            Expression *school = new TerminalExpression(schools);
            Expression *student = new TerminalExpression(students);
            schoolStudent = new AndExpression(school,student);
        }
        void enterCan(string mess)
        {
            bool ok=schoolStudent->interpret(mess);
            cout<<"ok "<<ok<<endl;
            if(ok)
                cout<<"这个学生是: "<<mess<<" 可以进入校园!"<<endl;
            else
                cout<<mess<<" 不可以进入校园!"<<endl;
        }
    
    private:
        vector<string> schools={"清华","北大"};
        vector<string> students={"明明","红红","蓝蓝"};
        Expression *schoolStudent;
};

第五步:客户端

代码语言:javascript
复制
int main()
{
    Context *per = new Context();
   per->enterCan("清华的明明");//1 一个空格耽误我一个小时
   //per->enterCan("清华的喵喵");
    per->enterCan("北大的东东");
  // per->enterCan("北大的红红");

}

显示:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档