设计模式--解释器模式

解释器模式:属于行为型模式
基本原理:创建解释器,来解释特定的上下文。通俗一点就是类似,先定义一个文本,再查看指定的关键字是否符合需求的在文本中。
主要流程:
            1.创建解释器类的终结符表达式类,就是用来判断关键词是否在关键字集合中。
            2.创建解释器类的非终结符表达式类,利用终结符表达式类来判断关键字是否符合条件的在集合中。
            3.定义一个环境类,它包含解释器需要的数据(即关键字集合),完成对终结符表达式的初始化,并调用非终结符表达式来进行解释。
注意:核心点有两个非终结符表达式类、终结符表达式类

#include <iostream>
#include <string>
#include <vector>
using namespace std;

//创建解释器的基类
class Expression
{
public:
    virtual bool interpret(string context) = 0;
};

void MakeNext(const string &p, vector<int> &next)
{
    int q,k;
    int m=p.size();
    next[0] = 0;
    for(q=1,k=0; q<m; ++q)
    {
        while(k>0 && p[q]!=p[k])
        {
            k=next[k-1];
        }
        if(p[q] == p[k])
        {
            ++k;
        }
        next[q] = k;
    }
}
//非终结符表达式类中进行比较集合(或文本)和关键字的方法(这里使用的是KMP算法)
bool KmpMatch(const string &T, const string &P)
{
    vector<int> next(40,0);
    int n,m;
    n = T.size();
    m = P.size();
    MakeNext(P,next);
    for(int i=0,q=0; i<n; ++i)
    {
        while(q>0 && P[q]!=T[i])
        {
            q = next[q-1];
        }
        if(P[q]==T[i])
        {
            ++q;
        }
        if(q == m)
        {
            return true;
        }
    }
    return false;
}
//非终结符表达式类,用来检查关键字是否在文本(集合)中
class TerminalExpression : public Expression
{
private:
    string data;
public:
    //传入文本
    TerminalExpression(string data)
    {
        this->data = data;
    }
    //传入关键字,并返回检查的结果
    bool interpret(string context)
    {
        //调用比较的方法
        if(KmpMatch(context,data))
        {
            return true;
        }
        return false;
    }
};

//终结符表达式类,利用非终结符表达式来进一步的解释
class OrExpression : public Expression
{
private:
    Expression *expr1 = NULL;
    Expression *expr2 = NULL;
public:
    //传入非终结符表达式类
    OrExpression(Expression *expr1, Expression *expr2)
    {
        this->expr1 = expr1;
        this->expr2 = expr2;
    }
    //进行比较,这里是两个非终结符表达式是否有一个为真
    bool interpret(string context)//传入关键字
    {
        return expr1->interpret(context) || expr2->interpret(context);
    }
};
//终结符表达式类
class AndExpression : public Expression
{
private:
    Expression *expr1 = NULL;
    Expression *expr2 = NULL;
public:
    AndExpression(Expression *expr1, Expression *expr2)
    {
        this->expr1 = expr1;
        this->expr2 = expr2;
    }
    //进行比较,这里是两个非终结符表达式是否都为真
    bool interpret(string context)
    {
        return expr1->interpret(context) && expr2->interpret(context);
    }
};

//环境类(也可以是方法),初始化非终结符表达式类,传入文本(集合),并返回终结符表达式类用来进一步解释
Expression *getMaleExpression()
{
    Expression *robert = new TerminalExpression("Robert");
    Expression *john = new TerminalExpression("John");
    return new OrExpression(robert, john);
}
Expression *getMarriedWomanExpression()
{
    Expression *julie = new TerminalExpression("Julie");
    Expression *married = new TerminalExpression("Married");
    return new AndExpression(julie, married);
}

int main()
{
    Expression *isMale = getMaleExpression();
    Expression *isMarriedWoman = getMarriedWomanExpression();
    //调用返回的终结符表达式类,传入关键字进行比较,得到最终的结果
    cout<<"John is male? "<<isMale->interpret("John")<<endl;
    cout<<"Julie is a married women? "<<isMarriedWoman->interpret("Married Julie")<<endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值