解释器模式
解释器模式:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。(不常用)
角色:1.AbstractRxpression抽象解释器:具体点的解释任务由各个实现类完成。
2.TerminalExpression终结符表达式:实现与文法中的元素相关联的解释操作。
3.NonterminalExpression非终结符表达式:文法中的每条规则对应于一个非终结表达式。
4.Context环境角色
适用场景:重复发生的问题。
具体实现:先输入一个公式,再给公式中的字符赋值,输出结果
通用实现
1.创建抽象表达式类
/**
* 抽象表达式类
* 抽象解释器
*/
public abstract class Expression {
//解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字
public abstract int interpreter(HashMap<String,Integer> var);
}
2.创建变量解析器
/**
* 变量解析器
* 终结符表达式角色
*/
public class VarExpression extends Expression{
private String key;
public VarExpression(String key){
this.key = key;
}
//从map中取之
public int interpreter(HashMap<String,Integer> var){
return var.get(this.key);
}
}
3.创建抽象运算符号解析器
/**
* 抽象的运算符号解析器
* 抽象的非终结符表达式
*/
public abstract class SymbolExpression extends Expression{
protected Expression left;
protected Expression right;
//所有的解析公式都应值关心自己左右两个表达式的结果
public SymbolExpression(Expression left,Expression right){
this.left = left;
this.right = right;
}
}
4.创建加法解析器和减法解析器
/**
* 加法解析器
* 具体的非终结符表达式
*/
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left,Expression right){
super(left, right);
}
//把左右两个表达式运算的结果加起来
public int interpreter(HashMap<String,Integer> var)
{
return super.left.interpreter(var)+super.right.interpreter(var);
}
}
/**
* 减法解析器
* 具体的非终结符表达式
*/
public class SubExpression extends SymbolExpression{
public SubExpression(Expression left,Expression right){
super(left, right);
}
//把左右两个表达式运算的结果相减
public int interpreter(HashMap<String,Integer> var)
{
return super.left.interpreter(var)-super.right.interpreter(var);
}
}
5.创建解析器封装类
/**
* 解析器封装类
*/
public class Calculator {
//定义表达式
private Expression expression;
//构造函数传参,并解析
public Calculator(String expStr){
//定义一个栈,安排运算的先后顺序
Stack<Expression> stack = new Stack<>();
//表达式拆分为字符数组
char[] charArray = expStr.toCharArray();
//运算
Expression left = null;
Expression right = null;
for(int i = 0;i<charArray.length;i++){
switch (charArray[i]){
case '+': //加法
//把加法结果放入栈中
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new AddExpression(left,right));
break;
case '-': //减法
//把加法结果放入栈中
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left,right));
break;
default: //公式中的变量
stack.push(new VarExpression(String.valueOf(charArray[i])));
}
}
//把运算结果抛出来
this.expression = stack.pop();
}
//开始运算
public int run(HashMap<String,Integer> var){
return this.expression.interpreter(var);
}
}
6.创建场景测试类
/**
* 场景测试类
*/
public class Client {
//进行四则运算
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
//赋值
HashMap<String,Integer> var = getValue(expStr);
Calculator cal = new Calculator(expStr);
System.out.println("运算结果为:"+expStr+"="+cal.run(var));
}
//获得表达式
public static String getExpStr() throws IOException {
System.out.println("请输入表达式");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
//获得值映射
public static HashMap<String,Integer> getValue(String exprStr) throws IOException {
HashMap<String,Integer> map = new HashMap<>();
//解析有几个参数要传递
for(char ch:exprStr.toCharArray()){
if(ch !='+' && ch !='-'){
//解决重复参数问题
if(!map.containsKey(String.valueOf(ch))){
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch),Integer.valueOf(in));
}
}
}
return map;
}
}