名企刷题
剑指Offer分类练习
现实需求:有些问题多次重复出现,而且有一定的相似性和规律性。
解释器模式:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
优点:
扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。
缺点:
执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
2. 可应用的场景比较少。
主要角色。
抽象表达式角色:定义解释器的接口,约定解释器的解释操作。
终结符表达式角色:抽象表达式的子类,实现文法中与终结符相关的操作。
非终结符表达式角色:抽象表达式的子类,实现文法中与非终结符相关的操作。
环境角色:包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
客户端:用解释器的解释方法,通过环境角色间接访问解释器的解释方法。
具体案例:小码路接了公司一项目,为北大清华的学生制作出入证,先找到学校学生可以进步,如果找不到侧拒绝进入校园。
第一步:抽象表达式
#include #include #include #include #include #include using namespace std;//抽象表达式class Expression{ public: virtual bool interpret(string mess)=0;};
第二步:终结符表达式
//终结符表达式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;};
第三步:非终结符表达式
//非终结符表达式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;};
第四步:环境类
//环境类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;};
第五步:客户端
int main(){ Context *per = new Context(); per->enterCan("清华的明明");//1 一个空格耽误我一个小时 //per->enterCan("清华的喵喵"); per->enterCan("北大的东东"); // per->enterCan("北大的红红");}
显示:
推荐阅读
设计模式之里氏替换原则C++实现
设计模式之开闭原则C++实现
设计模式之依赖倒置原则C++实现
设计模式之单一职责原则C++实现
设计模式之接口隔离原则C++实现
设计模式之迪米特法则C++实现
创建型之单例模式C++实现
创建型之工厂方法模式C++实现
创建型之原型模式C++实现
创建型之抽象工厂模式C++实现
创建型之建造者模式C++实现
结构型之代理模式C++实现
结构型之适配器模式C++实现
结构型之装饰模式C++实现
结构型之外观模式C++实现
结构型之桥接模式C++实现
结构型之组合模式C++实现
结构型之享元模式C++实现
行为型之模板方法C++实现
行为型之策略模式C++实现
行为型之状态模式C++实现
行为型之责任链模式C++实现
行为型之命令模式C++实现
行为型之访问者模式C++实现