Java解析表达式
需求
指定一个String表达式,表达式符合给出的运算符规范,比如:2!=2 and 2>=3 or 4<=4,计算出表达式的结果(true or false)。 支持的操作符:(,),and,or,mod,+,-,*,/,>,>=,<,<=,=,!=思路
1. 首先要用Java运算符替换表达式中的部分操作符,如and替换为&&,or替换为||,具体如下: ``` operatorsMap.put("\\s+and\\s+", "&&"); operatorsMap.put("\\s+or\\s+", "||"); operatorsMap.put("\\s+mod\\s+", "%"); operatorsMap.put("(?|<|\\!|=)=(?!=|>|<|\\!)", "=="); operatorsMap.put("\\)and\\s+", ")&&"); operatorsMap.put("\\s+and\\(", "&&("); operatorsMap.put("\\)and\\(", ")&&("); operatorsMap.put("\\)or\\s+", ")||"); operatorsMap.put("\\s+or\\(", "||("); operatorsMap.put("\\)or\\(", ")||("); operatorsMap.put("\\)mod\\s+", ")%"); operatorsMap.put("\\s+mod\\(", "%("); operatorsMap.put("\\)mod\\(", ")%("); operatorsMap.put("\\!\\s+\\=", "!="); operatorsMap.put("\\>\\s+\\=", ">="); operatorsMap.put("\\<\\s+\\=", "<="); ``` 2. 将替换后的表达式,转化了一个```List //比如加法运算符,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";
}
}
- 返回布尔值
//List<String> mustList后缀表达式
//Map<String, Object> value表达式中变量的值
public boolean getResult(List<String> mustList, Map<String, Object> value) {
return Boolean.parseBoolean(compute(replace(mustList, value)));
}
总结
将表达式处理为后缀表达式,通过栈完成操作数的运算,是个比较经典的小程序,比较考验计算机功底和细节处理。
I am a slow walker, but I never walk backwards.