设计模式之解释器模式(C++)
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
一、解释器模式是什么?
解释器模式是一种行为型的软件设计模式,定义了一个解释器,来解释给定语言和文法的句子。也可以理解为翻译吧,比如1+1,翻译为一加上一,等于二,这样就做成了一个简单的加法计算器。
解释器模式的优点:
- 良好扩展性。语法的翻译通过类来实现,扩展类可以扩展其解释能力。
- 易实现。语法树中每个表达式节点类具备一定相似性,实现起来相对容易。
解释器模式的缺点:
- 执行效率低。解释器中通常有大量循环和递归语句,当被解释句子较复杂时,程序的性能受到较大影响。
- 类膨胀。规则较多时,类数量也膨胀。
二、解释器模式
2.1 结构图
客户端即Main主函数,客户端通过解释器来解析表达式内容,表达式又分为终结型和非终结型。就拿计算器举例,1+1,1就是终结符类型,表达式可以用它结尾;而+就是非终结符类型,出现了+,就意味着它前后还有别的表达式字符,自然不能作终结。
2.2 代码示例
场景描述:实现简单的加减法计算器。
//Interpreter.h
/****************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>using namespace std;// 抽象表达式类
class Expression
{
public:// 解释virtual int interpret() = 0;};// 数字表达式类
class NumberExpression : public Expression
{
public:// 构造函数NumberExpression(int num) : number(num) {}// 解释virtual int interpret() { return number; }private:int number;
};// 加法表达式类
class AddExpression : public Expression
{
public:// 构造函数AddExpression(Expression* left, Expression* right) : left(left), right(right) {}// 解释virtual int interpret() { return left->interpret() + right->interpret(); }private:Expression* left;Expression* right;
};// 减法表达式类
class SubExpression : public Expression
{
public:// 构造函数SubExpression(Expression* left, Expression* right) : left(left), right(right) {}// 解释virtual int interpret() { return left->interpret() - right->interpret(); }private:Expression* left;Expression* right;
};// 解释器类
class Interpreter
{
public:// 构造函数Interpreter(string exp) : expression(exp) {}// 解释int interpret() {stack<Expression*> s;// 遍历表达式字符for (int i = 0; i < expression.length(); i++) {if (isdigit(expression[i])) {// 识别数字int j = i;while (j < expression.length() && isdigit(expression[j])) {j++;}int num = stoi(expression.substr(i, j - i));s.push(new NumberExpression(num));i = j - 1;}else if (expression[i] == '+') {// 把左数提取出来Expression* left = s.top();s.pop();// 识别右数int j = i + 1;while (j < expression.length() && isdigit(expression[j])) {j++;}Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));// 左数+右数的表达式放入栈中s.push(new AddExpression(left, right));i = j - 1;}else if (expression[i] == '-') {// 把左数提取出来Expression* left = s.top();s.pop();// 识别右数int j = i + 1;while (j < expression.length() && isdigit(expression[j])) {j++;}Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));// 左数-右数的表达式放入栈中s.push(new SubExpression(left, right));i = j - 1;}}return s.top()->interpret();}private:string expression;
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include <unordered_map>
#include "Interpreter.h"using namespace std;int main()
{unordered_map<string, int> variables;string input;while (getline(cin, input)) {cout << "input:" << input << endl;Interpreter interpreter(input);variables[input] = interpreter.interpret();cout << "result:" << variables[input] << endl;}return 0;
}
程序结果如下。
上述实现的简易计算器,也是许多大学C/C++课程中的大作业,记得以前用MFC实现了一款计算器,开心了老半天哈哈,梦回大学。感兴趣的同学也可以试试复杂计算器,比如引入了括号还有各类运算符。
三、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对解释器模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解解释器模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
相关文章:

设计模式之解释器模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、解释器模式是什么? 解释器模式是一种行为型的软件设计模式,定义了一个解释器,来解释给定语…...
基于MATLAB编程的粒子群算法优化BP神经网络风电功率预测,基于PSO-BP的风电功率预测
目录 摘要 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 粒子群算法的原理及步骤 基于粒子群算法改进优化BP神经网络的风电功率 matlab代码 代写下载链接:https://download.csdn.net/download/a…...
开心档之C++ 字符串
C 字符串 目录 C 字符串 C 风格字符串 实例 实例 C 中的 String 类 实例 C 提供了以下两种类型的字符串表示形式: C 风格字符串C 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 …...

Java Collection源码分析(JDk corretto 11)
文章目录 Collection 系列源码分析 (JDK Amazon corretto 11)Collection接口Iterable接口 子接口 QueueQueue的子接口 Deque双端队列 子接口ListArrayList 实现类序列化与反序列化(后续解决)获取Calss对象的方式 主要有三种:Arrays工具类System类 LinkedList实现类t…...

13种权重的计算方法
权重计算方法有很多种,不同的方法有不同的特点和适用情况。AHP层次分析法和熵值法在权重计算中属于比较常用的方法。除此之外,还有一些与权重计算相关的方法,今天一文总结了13种与权重计算相关的方法,大家可以对比选择使用。 一、…...

Devops和Gitops区别
一. 什么是devops DevOps 是一种开发(Dev)和运维(Ops)之间协作和沟通的文化、流程和工具的实践方法。它强调迭代、快速交付和持续集成/持续交付,旨在加速软件交付的速度、质量和稳定性。 DevOps 的核心目标是通过自动…...

拿下多家车企定点!4D毫米波雷达「域」系统首发出道
从1R、2R、3R到整车360感知方案,毫米波雷达的前装市场需求量依然保持着快速增长的态势。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)前装标配搭载ADAS毫米波雷达(前向后向盲区)交付1795.…...

【FATE联邦学习】FATE联邦学习使用GPU、指定cuda下标
问题 FATE框架1.x支持GPU训练吗? 寻找 先看了官网,搜官网,发现还是有的。 打开第一个后,里面可以用training param指定各个client的训练GPU,但是好像都是在large language model的。 而在文档中搜寻到的gpu…...
英文数字表达
1基数词 0 nought;zero;O 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 10 ten 11 eleven 12 twelve 13 thirteen 14 fourteen 15 fifteen 16 sixteen 17 seventeen 18 eighteen 19 nineteen 20 twenty21 twenty-one 22 twenty-two 23 twenty-three 30 th…...

第11届蓝桥杯省赛真题剖析-2020年6月21日Scratch编程初中级组
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第125讲。 第11届蓝桥杯省赛,这是2020年6月21日举办的省赛Scratch考试真题,原定于2020年3月7日…...

部署LVS-NAT群集实验
一、 实验准备 负载调度器:内网关 ens33:192.168.109.12,外网关 ens37:12.0.0.1外网 Web节点服务器1:192.168.109.13 Web节点服务器2:192.168.109.14 NFS服务器:192.168.109.11 客户端…...
对待工作的九个级别
只要是职场人,每天都要开展本职工作,有的人在职场上混得风生水起、平步青云,有的人却总是在原地踏步踏,总有一种怀才不遇的感叹,为什么呢?其实,差距就在于对待工作的态度上。 今天我们一起与各位…...
第四章 存储结构与管理硬盘
第四章 存储结构与管理硬盘 一、一切从“/”开始 1、Linux系统中常见的目录名称以及相应内容 目录名称应放置文件的内容/boot开机所需文件——内核、开机菜单以及所需配置文件等/dev以文件形式存放任何设备与接口/etc配置文件/home用户主目录/bin存放单用户模式下还可以操作…...

【腾讯云-2】极简搭建边缘集群
1 创建 流程和https://blog.csdn.net/qq_47058489/article/details/130347795差不多,可参考 查看基本信息: 创建边缘集群的过程中会初始化master,说明包含一个托管master节点 但是没有其他节点 2 开启节点远程登录 通过 SSH 的方式远…...
在springboot中给mybatis加拦截器
拦截器的作用就是我们可以拦截某些方法的调用,在目标方法前后加上我们自己逻辑 Mybatis拦截器设计的一个初衷是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。 mybatis 自定义拦截器 1、实现Interceptor 接口,并添加拦截注解 I…...

[oeasy]python0139_尝试捕获异常_ try_except_traceback
尝试捕获异常 回忆上次内容 变量相加 整型数字变量可以相加字符串变量也可以拼接 但是 字符串 和 整型数字整型数字 和 字符串不能相加 怎么办? 转格式int(“1”)str(2) 可是 如果输入的苹果数量是 字符串"abc" int(“abc”)会发生什么?&…...

树的刷题,嗝
今天忘记带本子了,就没有学习java了,于是一心刷题,好烦遇到了两个奇怪的题目,我没跟题解写的,但是我是没想到奇怪的样例. no.1 617. 合并二叉树 难度简单1221收藏分享切换为英文接收动态反馈 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中…...

举个栗子~Tableau 技巧(253):让筛选器只显示全部以及需要的类别
用户反馈了一个需求:我的业务数据有很多类别,但其实经常查看的只有几个,Tableau 筛选器能不能设置一下,只显示全部和经常查看的那几个类别? 这个是可以实现的!如下示例,数据类别有:…...
服务器温度过高告警
今天巡检一套rac环境,发现节点二上有Error字样,逐行看完细节是服务器温度过高导致的,半夜又没啥业务的,查看硬件也没任何告警,哎,某品牌的品控确实越来越烂,log一下 Mar 21 02:53:21 hydb1 ker…...

反垃圾邮件产品测试评价方法示意图
声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品测试评价方法 测试环境 反垃圾邮件产品的典型测试环境如图1所示。 图1 反垃圾邮件产品典型测试环境示意图 测试设…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...