应用场景
解释器模式,英文名Interpreter Pattern
这是一个比较专业的模式,它专门用于公式解析或语法解析类的问题
该模式通过一个专门的解释器类,根据用于输入的表达式和参数,来计算出运算结果
该模式并没有固定形式,解释器如何实现完全取决于实际问题
但大多公式和语法类问题,解决方法都会涉及递归运算、栈、二叉树等知识
实现代码
这里以加减法为例,实现一个最简单的公式解释器
//数学表达式
//一个总的表达式,可以视为若干个子表达式,进行多次组合运算后得到的结果
//这样我们就可以抽象出表达式这个类,表达式是可以运算的,并且运算得到的结果仍然是表达式
//表达式可分为两大类:
//一类是变量表达式,即公式中的a、b、c、d等参数,是一种最小粒度的表达式,不可再拆分
//一类是符号表达式,即一个表达式与另一个表达式,进行加减乘除后得到的新表达式
abstract public class Expression {
//输入参数值,计算表达式结果
//params是公式中a、b、c、d等参数对应的实际数值
abstract public int interpret(Map<String, Integer> params);
}
//变量表达式
public class VarExpression extends Expression {
String var;
public VarExpression(String var) {
this.var = var;
}
@Override
public int interpret(Map<String, Integer> params) {
return params.get(var);
}
}
//符号表达式
abstract public class SymbolExpression extends Expression {
Expression leftExpression;
Expression rightExpression;
//两个子表达式进行运算,得到新表达式
public SymbolExpression(Expression leftExpression, Expression rightExpression) {
this.leftExpression = leftExpression;
this.rightExpression = rightExpression;
}
}
//加法表达式
public class AddExpression extends SymbolExpression {
public AddExpression(Expression leftExpression, Expression rightExpression) {
super(leftExpression, rightExpression);
}
@Override
public int interpret(Map<String, Integer> params) {
return leftExpression.interpret(params) + rightExpression.interpret(params);
}
}
//减法表达式
public class SubExpression extends SymbolExpression {
public SubExpression(Expression leftExpression, Expression rightExpression) {
super(leftExpression, rightExpression);
}
@Override
public int interpret(Map<String, Integer> params) {
return leftExpression.interpret(params) - rightExpression.interpret(params);
}
}
//计算器类,将输入的公式解析为表达式,并计算结果
public class Calculator {
//输入公式和参数值,计算表达式结果
public static int calculate(String expression, Map<String, Integer> params) {
//读取公式中的全部字符
String[] chars = new String[expression.length()];
for (int i = 0; i < expression.length(); i++)
chars[i] = expression.charAt(i) + "";
//从左到右,让表达式逐个入栈
//每当遇到加号或减号时,就让前面的表达式出栈,作为加法运算或减法运算的leftExpression
//加减法是一种最简单的运算,所有运算符的优先级是一样的,从左往右执行即可
//对于更复杂的表达式,可以利用二叉树结构来实现
Stack<Expression> stack = new Stack();
Expression leftExp = null;
Expression rightExp = null;
for (int i = 0; i < expression.length(); i++) {
switch (chars[i]) {
case "+":
leftExp = stack.pop();
rightExp = new VarExpression(chars[++i]);
stack.push(new AddExpression(leftExp, rightExp));
break;
case "-":
leftExp = stack.pop();
rightExp = new VarExpression(chars[++i]);
stack.push(new SubExpression(leftExp, rightExp));
break;
default:
stack.push(new VarExpression(chars[i]));
break;
}
}
//取出总表达式,计算结果
Expression finalExpression = stack.pop();
int result = finalExpression.interpret(params);
return result;
}
}
public class APP {
public static void main(String... args) {
String expression = "a+b-c-d";
Map<String, Integer> params = new HashMap();
params.put("a", 5);
params.put("b", 4);
params.put("c", 2);
params.put("d", 4);
int result = Calculator.calculate(expression, params);
System.out.println(result);
}
}