面试遇到了这个题,里面需要用到根据配置的四则运算式(字符串型),计算公式结果,搜了之后,在网上看到这个
http://www.blogjava.net/luluyanglu/archive/2010/04/21/318964.html
因为在处理四则运算的时候最麻烦的逻辑主要是对括号内预算的处理,特别是括号的嵌套。
因此该算法主要的逻辑是,通过对括号位置的观察,得出:从左至右的扫描一个字符串,那么每一个右括号将与最近遇到的那个未匹配的左括号相匹配。这和堆栈的后进先出的规则是一样的。因此得到在扫描的过程当中,将每一个遇到的左括号进行压栈,在出现右括号的时候,出栈。
该解法相对于通过递归实现的解法,在时间复杂性上略好,并且实现出来的代码更加清晰。
package com.exam;
import java.util.ArrayList;
import java.util.LinkedList;
/**
*
* @author l
*
*/
public class Exam2 {
private boolean isRightFormat = true;
public double getResult(String formula) {
double returnValue = 0;
try {
returnValue = doAnalysis(formula);
} catch (NumberFormatException nfe) {
System.out.println("公式格式有误,请检查:" + formula);
} catch (Exception e) {
e.printStackTrace();
}
if (!isRightFormat) {
System.out.println("公式格式有误,请检查:" + formula);
}
return returnValue;
}
private double doAnalysis(String formula) {
double returnValue = 0;
LinkedList<Integer> stack = new LinkedList<Integer>();
int curPos = 0;
String beforePart = "";
String afterPart = "";
String calculator = "";
isRightFormat = true;
while (isRightFormat
&& (formula.indexOf('(') >= 0 || formula.indexOf(')') >= 0)) {
curPos = 0;
for (char s : formula.toCharArray()) {
if (s == '(') {
stack.add(curPos);
} else if (s == ')') {
if (stack.size() > 0) {
beforePart = formula.substring(0, stack.getLast());
afterPart = formula.substring(curPos + 1);
calculator = formula.substring(stack.getLast() + 1,
curPos);
formula = beforePart + doCalculation(calculator)
+ afterPart;
stack.clear();
break;
} else {
System.out.println("有未关闭的右括号!");
isRightFormat = false;
}
}
curPos++;
}
if (stack.size() > 0) {
System.out.println("有未关闭的左括号!");
break;
}
}
if (isRightFormat) {
returnValue = doCalculation(formula);
}
return returnValue;
}
private double doCalculation(String formula) {
ArrayList<Double> values = new ArrayList<Double>();
ArrayList<String> operators = new ArrayList<String>();
int curPos = 0;
int prePos = 0;
for (char s : formula.toCharArray()) {
if (s == '+' || s == '-' || s == '*' || s == '/') {
values.add(Double.parseDouble(formula.substring(prePos, curPos)
.trim()));
operators.add("" + s);
prePos = curPos + 1;
}
curPos++;
}
values.add(Double.parseDouble(formula.substring(prePos).trim()));
char op;
for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
op = operators.get(curPos).charAt(0);
switch (op) {
case '*':
values.add(curPos, values.get(curPos) * values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
case '/':
values.add(curPos, values.get(curPos) / values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
}
}
for (curPos = operators.size() - 1; curPos >= 0; curPos--) {
op = operators.get(curPos).charAt(0);
switch (op) {
case '+':
values.add(curPos, values.get(curPos) + values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
case '-':
values.add(curPos, values.get(curPos) - values.get(curPos + 1));
values.remove(curPos + 1);
values.remove(curPos + 1);
operators.remove(curPos);
break;
}
}
return values.get(0).doubleValue();
}
}
分享到:
相关推荐
四则运算解析器 解析字符串运算式 代码简单 新手福利
解析expression四则运算表达式 如:(1+2*3.5*(2+3)-10+18*20)
例: Expression e = new [removed]"1+2*((3+5)/10*5*4 +(1-2)/4)"); System.out.println(e.eval());//32.5 要求jdk1.6
今天小编就为大家分享一篇java实现字符串四则运算公式解析工具类的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
将近250行的算法 实现了通过字符串进行加减乘除四则运算 纯通过处理字符串和数组实现 希望能帮助大家: 例如:String input "33+26 77+70"; String result ""; try { result Account...
java正则实现解析算术表达式 (仅限+-*/和括号)
在编写代码时我们有时候会碰到需要自己解析四则运算表达式的情况,本文简单的介绍使用JavaScript实现对简单四则运算表达式的解析。 一、熟悉概念 中缀表示法(或中缀记法)是一个通用的算术或逻辑公式表示方法, ...
解析字符串换算为四则运算公式根据优先级进行数字运算
设计模式之解释器模式的Java版本实现和UML类图设计
本程序实现一个四则混合运算,用户只需要输入四则混合运算表达式,程序自动计算, 可以一次计算一个表达式,也可以批量计算多行表达式,而且适合商业计算精度要求。 由于该程序依赖一个清屏功能cls.dll,使用32位win7...
加减乘除多重括号的复杂计算,只需输入你要计算的字符串,立马出正确结果,而且有打印出计算步骤,非常强大,用解析字符串做出来的。望下载后觉得好用的给点好评,望大家顶顶!
算符优先分析法的实现,对四则运算表达式解析有帮助
可解析带括号的四则运算。 解析算术表达式的时候,准备调用Webkit通过Js来解析的。 但是2.3.3存在Bug,Js调用Java会导致程序崩溃, 所以没办法,最后是用 BeanShell来解析的。 不过,因为需要每个参与计算的数字...
27.1 四则运算你会吗 27.2 解释器模式的定义 27.3 解释器模式的应用 27.3.1 解释器模式的优点 27.3.2 解释器模式的缺点 27.3.3 解释器模式使用的场景 27.3.4 解释器模式的注意事项 27.4 最佳实践 第28章 享元模式 ...
一般java的常规计算方法的总结和归类,包涵四则运算的集合
Date类中包含了日期和时间,在Java编程中,日期通常指年、月、日,时间则指时、分、秒、毫秒。Java对Date进行格式化使用java.text.DateFormat类。在格式表示中,经常采用4种格式,这四种格式被定义为DateFormat类的...
但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...
IK Expression是一个开源的(OpenSource),可扩展的(Extensible),基于java语言开发的一个超轻量级(Super lightweight)的公式化语言解析执行工具包。 IK ExpressionV2.0不依赖于任何第三方的java库。它做为一...
但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...