持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
导言
说解释器模式之前,我们先理解下解释器,这个其实对我们开发而言,应该是很熟悉的了,例如我们的编程语言,Java、PHP、C++、JavaScript等高级语言,我们编写的代码计算机是看不懂的,它只会执行0和1编码,这中间就需要进行翻译,把我们写的代码解释为机器能够识别的0/1二进制码。
再举个例子,HTML超文本标记语言中,前端开发的div、span、p标签和样式只所以在网页中能呈现出各种花里胡哨的样子,是因为浏览器解释器已经定义出了一套针对和标签和样式如何渲染的机制。
解释器其实就是在输入和输出之间的一个翻译工具,让输出方能够识别输入的信息,从而执行对应的任务。解释器模式就是这样一个提供中间方解释的设计模式,它需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
罗马数字转整数
在leetcode第13题罗马数字转整数,就需要我们提供一个解释器来把输入的罗马数字转成输出的整数。
var romanToInt = function(s) {
if (!s) return 0
let ret = 0
s = s.replace(/IV/g, ',4,')
s = s.replace(/IX/g, ',9,')
s = s.replace(/XL/g, ',40,')
s = s.replace(/XC/g, ',90,')
s = s.replace(/CD/g, ',400,')
s = s.replace(/CM/g, ',900,')
// 取出空
const arr = s.split(',')
const reg = /^[0-9]+$/
const digArr = arr.filter(item => {
return reg.test(item)
})
const azArr = arr.filter(item => {
return /^[A-Z]+$/.test(item)
})
for (let num of digArr) {
ret += Number(num)
}
const azStr = azArr.join().replace(/,/g, '')
for (let num of azStr) {
if (num == 'M') {
ret += 1000
} else if (num == 'D') {
ret += 500
} else if (num == 'C') {
ret += 100
} else if (num == 'L') {
ret += 50
} else if (num == 'X') {
ret += 10
} else if (num == 'V') {
ret += 5
} else if (num == 'I') {
ret += 1
}
}
return ret
}
romanToInt('III') // 3
数字间的转换是很简单的,特别是设计到底层的编程语言或脚本解释器是非常复杂的,中间也会涉及到更多的设计模式,但单看解释器模式本身而言,在不相通的输入和输出方间,单独解耦出一套解释模块,也就是解释器模式的宏观策略。