专栏首页mySoul设计模式-解释器模式
原创

设计模式-解释器模式

四则运算

模型公式,输入一个公式,然后输入其中的参数,然后运算出结果

代码如下

抽象表达式类

public abstract class Expression{
    // 解析数值,key是参数,value是数字
    public abstract int interpreter(HashMap<String, Integer> var);
}

变量解析器,根据此,可以获得保存在map中的键值对

public class VarExpress 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);
    }
}

抽象运算符号解析器

public abstract class SymbolExpression extends Expression{
    // 左数值
    protected Expression left;
    // 右数值
    protected Expression right;
    // 初始化
    public SymbolExpression(Expression _left, Expression _right){
        this.left = _left;
        this.right = _right;
    }
}

对加法进行解析

public class AddExpression extends SymbolExpression{
    public AddExpression(Expression _left, Expression _right){
        super(_left, _right);
    }
    // 进行相加
    public int interpreter(HashMap<String, Integer> var){
        // 取得,两边的变量都保存在HashMap表中,根据left和right变量,进行相加
        return super.left.interpreter(var) + super.right.interpreter(var);
    }
    // 进行相减
    public int interpreter(HashMap<String,Integer> var){
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}

再次对解析器进行封装,此为公式

public class Calculator{
    // 定义表达式
    private Expression expression;
    // 传参
    public Calculator(String expStr){
        // 用于先后顺序
        Stack 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(chrArray[++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.value(charArray[i])));
            }
        }
        // 运算结果抛出
        this.expression = stack.pop();
    }
    // 运算
    public int run(HashMap<String, Integer> var){
        return this.expression.interpreter(var);
    }
}

在上方中,完成的是对表达式的输入

最后场景

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("运算");
    }
    // 获得表达式
    public static String getExpStr() throws IOException{
        // 新建一个缓冲区,从缓冲区中读取数据
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }
    // 获得值映射
    public static HashMap<String, Integer> getValue(String expStr) throws IOException{
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        // 解析
        for(char ch:exprStr.toCharArray()){
            if(ch != '+' && != '-'){
                if(!map.containsKey(String.valueOf(ch))){
                    // 从缓冲区中,读取整行
                    String in = (new BufferReader(new InputStreamReader(System.in))).readLine();
                }
            }
        }
        return map;
    }
}

总结

解释器模式不难,核心思想在于构建语法树,进行运算的时候,进行递归调用。

具体做法是创建几个解释器,在创建一个解释器封装类,在解释器封装类中完成语法树的构建。然后在场景类中完成递归调用。

qrcode_for_gh_9901b36b3b0e_258.jpg

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式 开闭原则

    软件实体应该对扩展开放,对修改关闭,即实体应当通过扩展实现变化,而不是修改代码实现变化

    mySoul
  • DAO 设计模式

    客户发送数据到显示层,显示层发送数据到业务层,业务发送数据到数据层,数据层进行持久化.即.保存进入databases

    mySoul
  • 设计模式-原型模式

    关于Cloneable 接口,用途和Serializable一样为标记型接口,内部没有方法和属性,implements Cloneable 表示对象能被克隆,即...

    mySoul
  • 文字识别调用API(JAVA)

    _12291_721
  • Hadoop框架:HDFS读写机制与API详解

    第一个副本和client在一个节点里,如果client不在集群范围内,则这第一个node是随机选取的;第二个副本和第一个副本放在相同的机架上随机选择;第三个副本...

    知了一笑
  • 超详细!详解一道高频算法题:括号生成

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

    五分钟学算法
  • java中IO写文件工具类

    用户5166556
  • Java基础组件快速入门

    最近需要上线很多新的JAVA项目,然而很多JAVA的相关库都不太熟悉,项目实现起来遇到了不小阻力,熬了好几天夜。现在手头的工作基本完成了,因此打算好好来归纳下j...

    用户1216676
  • Mybatis3.2扫描ant通配符格式的typeAliasPackage

    业务场景:首先项目进行分布式拆分之后,按照模块再分为为api层和service层,web层。 其中订单业务的实体类放在com.muses.taoshop.it...

    SmileNicky
  • Java漫谈-String上

    String对象是不可变的。每次修改都是创建了一个全新的String对象,以包含修改后的字符串内容,最初的String对象在原处丝毫未动。

    汐楓

扫码关注云+社区

领取腾讯云代金券