解释器模式:属于行为型模式
基本原理:创建解释器,来解释特定的上下文。通俗一点就是类似,先定义一个文本,再查看指定的关键字是否符合需求的在文本中。
主要流程:
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;
}