需求

指定一个String表达式,表达式符合给出的运算符规范,比如:2!=2 and 2>=3 or 4,>=, 思路

1. 首先要用Java运算符替换表达式中的部分操作符,如and替换为&&,or替换为||,具体如下:
```
operatorsMap.put("\\s+and\\s+", "&&");
operatorsMap.put("\\s+or\\s+", "||");
operatorsMap.put("\\s+mod\\s+", "%");
operatorsMap.put("(?||\\s+\\=", ">=");
operatorsMap.put("\\```,Segment定义为:
```java
public Segment(String word,int type){
this.word = word;//词
this.type = type;//类型,如DIGIT = 1;LETTER = 2;
}
```
比如(ab+cd)/2 >= 3,解析后的Segment列表为:
```
segment1: (
segment2: ab
segment3: +
segment4: cd
segment5: )
segment6: /
segment7: 2
segment8: space
segment9: >=
segment10: space
segment11: 3
```
3. 将```List```转化为后缀表达式```List```,其中过滤掉空格(space)```Segment```
```java
public void doConvert(Segment segment) {
int type = segment.getType();
if (isBarcket(type)) { //括号的处理
dealBracket(segment);
} else if (isOperator(type)) {
dealOperator(segment);//运算符的处理
} else {
list.add(segment.getWord());//操作数的处理
}
}
```
4. 自定义各种运算符的计算规则
```java
operationMap.put("+", new PlusOperator());
operationMap.put("-", new MinusOperator());
operationMap.put("*", new MultipliedOperator());
operationMap.put("/", new DivideOperator());
operationMap.put("%", new ModOperator());
operationMap.put("^", new PowerOperator());
operationMap.put(">", new GtOperator());
operationMap.put("=", new GeOperator());
operationMap.put(" //比如加法运算符,PlusOperator:
public void operator(Deque<String> stack) {
//操作数出栈,完成运算
BigDecimal b = new BigDecimal(stack.pop());
BigDecimal a = new BigDecimal(stack.pop());
stack.push(a.add(b).stripTrailingZeros().toPlainString());
}


5. 计算后缀表达式的值。如果后缀表达式中操作数都是变量名,那么计算之前需要完成值的替换。
```java
public String compute(List<String> postfix) {
try {
Deque<String> stack = new ArrayDeque<>();
for (String item : postfix) {
Operator op = operationMap.get(item);
if (null == op) {
stack.push(item);
} else {
op.operator(stack);
}
}
return stack.pop();
} catch (Exception e) {
logger.info(e.getMessage(), e);
return "ERROR";
}
}
  1. 返回布尔值
//List<String> mustList后缀表达式
//Map<String, Object> value表达式中变量的值
public boolean getResult(List<String> mustList, Map<String, Object> value) {
return Boolean.parseBoolean(compute(replace(mustList, value)));
}

总结

将表达式处理为后缀表达式,通过栈完成操作数的运算,是个比较经典的小程序,比较考验计算机功底和细节处理。

Java解析表达式的更多相关文章

  1. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  2. JAVA上百实例源码以及开源项目

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...

  3. 集算器协助java处理多样性数据源之MongoDB

    MongoDB不支持join,其官网上推荐的unity jdbc可以把数据取出来进行二次计算实现join运算,但这些join.group.函数.表达式等高级功能都是收费版才有,而且即使是收费版本,对子 ...

  4. PL/0编译器(java version)–Praser.java

    1: package compiler; 2:   3: import java.io.IOException; 4: import java.util.BitSet; 5:   6: /** 7: ...

  5. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  6. Effective Java 第三版——12. 始终重写 toString 方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. JEECG 3.7.2版本发布,企业级JAVA快速开发平台

    JEECG 3.7.2版本发布 -  微云快速开发平台 JEECG是一款基于代码生成器的J2EE快速开发平台,开源界"小普元"超越传统商业企业级开发平台.引领新的开发模式(Onli ...

  8. java框架之Struts2(3)-OGNL&ValueStack

    OGNL 概述 OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的.功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用 ...

  9. 【cs229-Lecture2】Gradient Descent 最小二乘回归问题解析表达式推导过程及实现源码(无需迭代)

    视频地址:http://v.163.com/movie/2008/1/B/O/M6SGF6VB4_M6SGHJ9BO.html 机器学习课程的所有讲义及课后作业:http://pan.baidu.co ...

随机推荐

  1. Python用pip安装IPython/Jupyter最佳交互环境

    一.Python模块及安装包简介 如果说编程语言是武器,那么Python就是一把双管枪(Python2/Python3),而各种为Python编写的模块和包就是子弹.使用pip来填满我们的武器吧! I ...

  2. [转]FFMpeg框架代码阅读

    简介 FFmpeg是一个集录制.转换.音/视频编码解码功能为一体的完整的开源解决方案. FFmpeg的开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用.FFmpeg支持MPEG.Di ...

  3. JDK8安装时错误1335的解决

    Win7安装JDK8 update65版本时,碰到错误1335,错误信息大概是一个cab文件损坏了,搜索了一下,有网站提供这个错误的修补工具,不过最终我没有下载这个工具,说是系统问题,但工具不是MS官 ...

  4. python3学习笔记3---引用http://python3-cookbook.readthedocs.io/zh_CN/latest/

    2018-03-01数据结构和算法(3) 1.11 命名切片 假定你有一段代码要从一个记录字符串中几个固定位置提取出特定的数据字段(比如文件或类似格式): ###### 012345678901234 ...

  5. win10右键添加在此处打开powershell

    如图: 你想要的效果可能就是这个吧?但是找了好久没有找到方法?爸比告诉你,不需要修改任何东西, 解锁新姿势: 在文件夹空白处,按住shift同时鼠标右击,发现没??发现没!!!!

  6. 时间复杂度O(n),空间复杂度O(1)解斐波那契数列

    #include <stdio.h> #include <iostream> using namespace std; long long fibs1(int in_iN) { ...

  7. .net 弹出消息框后,页面样式变乱

    点击按钮,执行提交操作,弹出消息框后,页面的样式变乱,解决方法: 首先,确定使用的css样式正确,页面中的宽高值保持规范统一: 然后,弹出框避免使用Response.Write(),如下所示 Resp ...

  8. 智能指针之 shared_ptr

     std::shared_ptr 是通过指针保持对象共享所有权的智能指针.多个 shared_ptr 对象可占有同一对象大概实现了一下,主要实现原理为,共享指针内部持有堆资源 的指针以及引用计数的指针 ...

  9. Maven学习(三)-- 使用Maven构建项目

    摘自:http://www.cnblogs.com/xdp-gacl/p/4240930.html maven作为一个高度自动化构建工具,本身提供了构建项目的功能,下面就来体验一下使用maven构建项 ...

  10. 关于Java的散列桶, 以及附上一个案例-重写map集合

    为速度而散列: SlowMap.java说明了创建一个新的Map并不困难.但正如它的名称SlowMap所示,它不会很快,如果有更好的选择就应该放弃它.它的问题在于对键的查询,键没有按照任何特定的顺序保 ...