- 浏览: 420785 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (114)
- C++ (1)
- JAVA (58)
- sql,oracle,mysql (7)
- struts (2)
- tomcat (6)
- JS CSS (6)
- 其他 (7)
- javascript (4)
- exception (1)
- error (1)
- hashmap (1)
- hashset (1)
- python (1)
- sql (2)
- oracle (4)
- mysql (2)
- weblogic (3)
- session (2)
- http-only-cookie (1)
- httponly (1)
- cookie (1)
- ide (0)
- intellij (1)
- eclipse (2)
- idea (1)
- connection (2)
- maven (4)
- m2eclipse (2)
- m2e (2)
- InetAddress (1)
- DNS (1)
- web (1)
- goals (1)
- copy-dependencies (1)
- unpack (1)
- hash (1)
- 分布式 (1)
- gc (4)
- volatile (1)
- rsa (1)
- 加密 (1)
- 签名 (1)
- socket (1)
- tcp (1)
最新评论
-
xuxiaoyinliu:
谢谢,不错哦
有关cookie的httponly属性相关 -
雁行:
svn根本就不需要这么罗嗦的实现。
版本比较,直接出增量文件, ...
ant+cvs实现增量部署 -
ludatong110:
这个东西在IE里面会很明显的,我就碰到过IE中因为这个HTML ...
有关jqGrid应用里的字体大小不能控制的问题 -
labchy:
非常感谢 解决了问题
有关jqGrid应用里的字体大小不能控制的问题 -
tengyue5i5j:
Crusader 写道竟然有这么多人投良好。。。
楼主的思路有 ...
java实现一个栈,并提供取该栈中最大数的方法,复杂度O(1)
前言:最近涉及到业务人员配置数学表达式,要求解析并按照精度进行计算
参考了如下百度百科对逆波兰算法的讲解进行开发,开发过程中还参考了一篇精度算法的文章
1:http://baike.baidu.com/view/552648.htm
2:还有一遍文章忘了链接了,如果侵犯作者权利请告知,我立即删除
该类支持精度计算,支持负数,精度比较等功能。计算按照逆波兰方式解析。
/** * @Project: BizRule * @File: org.coffeesweet.util.MathExpress.java * @Author: coffeesweet * @Date: 2011-3-28 * @Description: 2011 coffeesweet Inc. All rights reserved. */ package org.coffeesweet.util; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author coffeesweet * +,-,*,/四则运算的表达式逆波兰解析计算类,精确计算,应用BigDecimal类处理 * 支持负数,但规范除整个表达式第一个数为负数时可以不出现在'('后,其它表达式中间任何位置的 * 负数必须出现在'('后,即:用括号括起来。比如:-3+(-2+1)*10或-3+((-2)+1)*10或(-3)+(-2+1)*10或(-3)+((-2)+1)*10 */ public class MathExpress { /** * + */ private final static String OP1 = "+"; /** * - */ private final static String OP2 = "-"; /** * * */ private final static String OP3 = "*"; /** * / */ private final static String OP4 = "/"; /** * ^ */ // private final static String OP5 = "^"; /** * % */ // private final static String OP6 = "%"; /** * ( */ private final static String OPSTART = "("; /** * ) */ private final static String OPEND = ")"; /** * !用来替代负数前面的'-' */ // private final static String NEGATIVESING = "!"; /** * !用来替代负数前面的'+' */ // private final static String PLUSSING = "@"; /** * '#'用来代表运算级别最低的特殊字符 */ // private final static String LOWESTSING = "#"; //最原始的四则运算式 private String expBase; //经过初始化处理后的四则运算式 private String expInited; //精度 private int precision=10; //取舍模式 private RoundingMode roundingMode=RoundingMode.HALF_UP; //精度上下文 private MathContext mc; //四则运算解析 private List<String> expList = new ArrayList<String>(); //存放逆波兰表达式 private List<String> rpnList = new ArrayList<String>(); public MathExpress(){ } public MathExpress(String expBase) { init(expBase,this.precision,this.roundingMode); } public MathExpress(String expBase,int precision,RoundingMode roundingMode){ init(expBase,precision,roundingMode); } public void init(String expBase,int precision,RoundingMode roundingMode){ this.expBase = expBase; this.precision = precision; this.roundingMode = roundingMode; this.mc = new MathContext(precision,roundingMode); this.expInited = initExpress(expBase); StringTokenizer st = new StringTokenizer(this.expInited,"+-*/^%()",true); while(st.hasMoreElements()){ this.expList.add(st.nextElement().toString().trim()); } this.rpnList = initRPN(this.expList); } /** * @return the expBase */ public String getExpBase() { return expBase; } /** * @param expBase the expBase to set */ public void setExpBase(String expBase) { this.expBase = expBase; } /** * @return the expInited */ public String getExpInited() { return expInited; } /** * @param expInited the expInited to set */ public void setExpInited(String expInited) { this.expInited = expInited; } /** * @return the precision */ public int getPrecision() { return precision; } /** * @param precision the precision to set */ public void setPrecision(int precision) { this.precision = precision; } /** * @return the roundingMode */ public RoundingMode getRoundingMode() { return roundingMode; } /** * @param roundingMode the roundingMode to set */ public void setRoundingMode(RoundingMode roundingMode) { this.roundingMode = roundingMode; } /** * @return the expList */ public List<String> getExpList() { return expList; } /** * @param expList the expList to set */ public void setExpList(List<String> expList) { this.expList = expList; } /** * @return the rpnList */ public List<String> getRpnList() { return rpnList; } /** * @param rpnList the rpnList to set */ public void setRpnList(List<String> rpnList) { this.rpnList = rpnList; } /** * @return the mc */ public MathContext getMc() { return mc; } /** * @param mc the mc to set */ public void setMc(MathContext mc) { this.mc = mc; } /** * 去除空白字符和在负号'-'前加'0',便于后面的StringTokenizer * @param exp * @return */ private static String initExpress(String exp){ String reStr = null; reStr = exp.replaceAll("\\s", ""); if(reStr.startsWith("-")){ reStr = "0"+reStr; } reStr = reStr.replaceAll("\\(\\-", "(0-"); return reStr; } /** * 是否是整数或是浮点数,但默认-05.15这种也认为是正确的格式 * @param str * @return */ private boolean isNumber(String str){ Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$"); Matcher m = p.matcher(str); boolean isNumber = m.matches(); return isNumber; } /** * 设置优先级顺序()设置与否无所谓 * @param sign * @return */ private int precedence(String str){ char sign = str.charAt(0); switch(sign){ case '+': case '-': return 1; case '*': case '/': return 2; case '^': case '%': return 3; case '(': case ')': // case '#': default: return 0; } } /** * 转变为逆波兰表达式 * @param strList * @return */ public List<String> initRPN(List<String> strList){ List<String> returnList = new ArrayList<String>(); //用来存放操作符的栈 Stack stack = new Stack(); // stack.push(LOWESTSING); int length = strList.size(); for(int i=0;i<length;i++ ){ String str = strList.get(i); if(isNumber(str)){ returnList.add(str); }else{ if(str.equals(OPSTART)){ //'('直接入栈 stack.push(str); }else if(str.equals(OPEND)){ //')' //进行出栈操作,直到栈为空或者遇到第一个左括号 while (!stack.isEmpty()) { //将栈顶字符串做出栈操作 String tempC = stack.pop(); if (!tempC.equals(OPSTART)) { //如果不是左括号,则将字符串直接放到逆波兰链表的最后 returnList.add(tempC); }else{ //如果是左括号,退出循环操作 break; } } }else{ if (stack.isEmpty()) { //如果栈内为空 //将当前字符串直接压栈 stack.push(str); }else{ //栈不空,比较运算符优先级顺序 if(precedence(stack.top())>=precedence(str)){ //如果栈顶元素优先级大于当前元素优先级则 while(!stack.isEmpty() && precedence(stack.top())>=precedence(str)){ returnList.add(stack.pop()); } } stack.push(str); } } } } //如果栈不为空,则将栈中所有元素出栈放到逆波兰链表的最后 while (!stack.isEmpty()) { returnList.add(stack.pop()); } return returnList; } /** * 计算逆波兰表达式 * @param rpnList * @return */ public String caculate(List<String> rpnList){ Stack numberStack = new Stack(); int length=rpnList.size(); for(int i=0;i<length;i++){ String temp=rpnList.get(i); if(isNumber(temp)){ numberStack.push(temp); }else{ BigDecimal tempNumber1 = new BigDecimal(numberStack.pop(),this.mc); BigDecimal tempNumber2 = new BigDecimal(numberStack.pop(),this.mc); BigDecimal tempNumber = new BigDecimal("0",this.mc); if(temp.equals(OP1)){ tempNumber=tempNumber2.add(tempNumber1); }else if(temp.equals(OP2)){ tempNumber=tempNumber2.subtract(tempNumber1); }else if(temp.equals(OP3)){ tempNumber=tempNumber2.multiply(tempNumber1); }else if(temp.equals(OP4)){ tempNumber=tempNumber2.divide(tempNumber1, precision, roundingMode); } numberStack.push(tempNumber.toString()); } } return numberStack.pop(); } /** * 按照类的缺省参数进行计算 * @return */ public String caculate(){ return caculate(this.rpnList); } /** * 数字条件表达式精确比较 * eg: "3.0>2" "1<5" "1==5" "1!=5" "(1.0+2)>3" "((-0.9+3)>=2. 1)" * 不支持&&,||等连接符 * @param str * @return */ public static boolean compareTo(String strParm){ boolean reBoolean = false; boolean isParentheses = false;//标记是否有()括上整个字符串 String str = initExpress(strParm); Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$"); Matcher m = p.matcher(str); isParentheses = m.matches(); if(-1==str.indexOf(">=")&&-1==str.indexOf("<=")&&-1==str.indexOf("==")&&-1==str.indexOf("!=")){ if(-1==str.indexOf(">")&&-1==str.indexOf("<")) throw new IllegalArgumentException("异常:条件表达式不正确!"); } if(-1 != str.indexOf(">=")){ String[] strTemps = str.split(">="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( -1 == r ){ reBoolean = false; }else{ reBoolean = true; } }else if(-1 != str.indexOf("<=")){ String[] strTemps = str.split("<="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 1 == r ){ reBoolean = false; }else{ reBoolean = true; } }else if(-1 != str.indexOf("==")){ String[] strTemps = str.split("=="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 0 == r ){ reBoolean = true; }else{ reBoolean = false; } }else if(-1 != str.indexOf("!=")){ String[] strTemps = str.split("!="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 0 != r ){ reBoolean = true; }else{ reBoolean = false; } }else if((-1 != str.indexOf(">")) && (-1 == str.indexOf("="))){ String[] strTemps = str.split(">"); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 1 == r ){ reBoolean = true; }else{ reBoolean = false; } }else if((-1 != str.indexOf("<")) && (-1 == str.indexOf("="))){ String[] strTemps = str.split("<"); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( -1 == r ){ reBoolean = true; }else{ reBoolean = false; } } return reBoolean; } public static void main(String...args){ // MathExpress me = new MathExpress("-(-0.5+0.1)*10+2",10,RoundingMode.HALF_UP); // System.out.println(me.getExpList()); // List<String> tempList = me.initRPN(me.getExpList()); // System.out.println(tempList); // String resultStr = me.caculate(tempList); // System.out.println(resultStr); MathExpress me = new MathExpress("-(-1.5000000003+0.1)*10+2"); String resultStr = me.caculate(); BigDecimal bd = new BigDecimal(resultStr); BigDecimal bd2 = bd.setScale(2, RoundingMode.HALF_UP); System.out.println(me.caculate()); System.out.println(bd.toString()); System.out.println(bd.scale()); System.out.println(bd2.toString()); System.out.println(bd2.scale()); // System.out.println("------------------------------------"); // Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$");//匹配类似以'('开头')'结尾的字符串 // Matcher m = p.matcher("(2. 0>2.22)"); // System.out.println(m.matches()); boolean reBoolean = MathExpress.compareTo("((-8.0+3)>=2. 1)"); System.out.println(reBoolean); } /** * 栈 */ private class Stack { LinkedList<String> stackList = new LinkedList<String>(); public Stack() { } /** * 入栈 * @param expression */ public void push(String expression) { stackList.addLast(expression); } /** * 出栈 * @return */ public String pop() { return stackList.removeLast(); } /** * 栈顶元素 * @return */ public String top() { return stackList.getLast(); } /** * 栈是否为空 * @return */ public boolean isEmpty() { return stackList.isEmpty(); } } }
发表评论
-
【Java TCP/IP Soket】— 消息边界的问题解决
2015-08-11 09:47 1462转自:http://blog.csdn.net/ ... -
java中volatile解释
2015-05-28 16:28 727http://www.cnblogs.com/aigongs ... -
Java中的substring真的会引起内存泄露么?
2015-05-27 13:18 961转: http://droidyue.com/blog/ ... -
成为Java GC专家(4)—Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响
2015-05-27 12:24 635转:http://www.importnew.com ... -
成为Java GC专家(3)—如何优化Java垃圾回收机制
2015-05-27 12:23 802转:http://www.importnew.com ... -
成为JavaGC专家(2)—如何监控Java垃圾回收机制
2015-05-27 12:20 656转:http://www.importnew.com ... -
成为JavaGC专家(1)—深入浅出Java垃圾回收机制
2015-05-27 12:16 521转:http://www.importnew.com ... -
《深入分析Java Web技术内幕》-样章示图总结
2013-01-17 11:46 1329试读完本书的样章章节后,感受颇深,其实单从样 ... -
eclipse中(装了插件m2eclipse后的)导入maven工程显示"感叹号"
2013-01-15 16:02 7389有时候导入一些开源工程(maven结构的),在 ... -
(转)分析模式 之 参与者(Party)
2012-10-22 16:39 965在我们分析模型的时 ... -
(转)java.sql.SQLException: (无法从套接字获取更多数据)数据大小超出此类型的最大值
2012-10-22 16:38 5534转至:http://linwei-211.i ... -
有关hashmap,hashset的相关总结
2011-09-16 17:32 3063这篇转自http://hi.baidu.com ... -
有关JAVA异常和错误(ERROR)的处理
2011-09-15 20:41 19189最近遇到有关ERROR的处理问题,下面这篇文章 转至: ... -
XFire 、Axis2、CXF、JWS、java6 区别 (转)
2011-06-13 22:50 1932XFire VS AxisXFire是与Axis2 并列的 ... -
转载[Connection reset,Connection reset by peer,Software caused connection abort :]
2011-06-08 13:16 10003Connection reset,Connection ... -
java实现一个栈,并提供取该栈中最大数的方法,复杂度O(1)
2011-06-07 15:18 2169记得是哪个面试题里的,这里只想到一个简单的方法,大家看看 ... -
Listener Servlet和filter的应用
2011-05-16 22:21 898下面这段话是小总结: Listener是Ser ... -
转载【有关JSP中的转发和重定向用法】
2011-05-15 19:05 1761转自: http://blog.csdn.net/cyhjr ... -
转载【Java对象的强、软、弱和虚引用】
2011-05-13 22:47 8991.Java对象的强、软、弱和虚引用 在JDK 1.2以 ... -
有关JNDI的理解
2011-04-14 11:22 978JAVA EE规范里的jndi是为了解决下面两个问题: ...
相关推荐
总的来说,这个Java版计算器项目涵盖了基本的算术运算、数据类型处理、字符串解析、栈数据结构的应用以及异常处理等多个Java编程核心概念,是学习和巩固编程技能的一个好练习。通过实际编写和测试这个计算器,开发者...
### Java面试宝典知识点解析 #### 一、Java基础部分 **1.1 多个类在一个.java文件中** - **问题**: 在一个`.java`源文件中是否可以包括多个类(不是内部类)? - **限制**: 可以包含多个类,但必须满足以下条件: ...
### JAVA习题库#第四章-方法知识点解析 #### 一、判断题知识点解析 **1. Java 语言的模块只有类。** - **答案:** 错误 - **解析:** 在Java中,除了类之外,还有接口(interface)、枚举(enum)等其他类型的模块。...
**测试**阶段,需要对各种复杂表达式进行测试,确保程序能够正确解析和计算,包括但不限于基本的四则运算、带有括号的嵌套表达式、以及各种数学函数的组合。 最后,在**总结**中,学生可能讨论了开发过程中的挑战、...
- **优势**:C#结合了Java和C++的优点,并在此基础上进行了创新和改进,如简化了语法、增强了安全性、提供了丰富的类库支持等。 - **应用场景**:C#广泛应用于Windows桌面应用、Web应用、游戏开发等多个领域。 - ...
- 字符串操作方法:concat、substring、indexOf等。 - 比较字符串:equals与==的区别。 - **引用传递及其应用** - 引用传递的深入理解:传递的是对象地址而非副本。 - 应用场景:修改对象状态。 - **this关键字*...
### Java算法练习题知识点解析 #### 1. 斐波那契数列 - **描述**:编写一个程序,计算斐波那契数列的前N项。 - **实现思路**: - 使用循环结构(如`for`循环)来依次计算每一项的值。 - 设置两个变量分别存储...
- `&`是按位与操作符,用于比较两个表达式的值,并返回一个布尔结果。 - `&&`是逻辑与操作符,同样用于比较两个表达式的值,但在某些情况下可以避免不必要的计算(短路逻辑)。 **3. Byte类型的-128怎么表示** - ...
- **解析**: 按 ESC 键并不是关闭数据库的标准方法。 ### 24. 逻辑型数据到整型数据转换 - **知识点**: 将逻辑型数据转换为整型数据时,True 通常转换为 -1,False 转换为 0。 - **解析**: 选项 D 正确描述了这种...
- **解析**:表达式中的运算会按照特定的优先级顺序进行。在给出的例子中,`X + 1` 的计算优先级最高。因此,正确答案是 D。 ### 12. 数据处理的最小单位 - **知识点**:数据处理的基本单元。 - **解析**:数据...
Java中,当两个整数进行除法运算时,结果也是整数,即结果会被截断而不是四舍五入。而乘法运算则遵循标准的数学运算规则。 **选择题解析:** 正确答案是 **C**:5000。 - `5688 / 1000` 的结果是 `5`(整数除法),...
大整数的四则运算 - **问题描述**:实现一个能够处理任意大小整数的加减乘除运算。 - **知识点**:大数算法,高精度计算。 #### 6. Hindex算法实现 - **问题描述**:实现 Hindex 算法。 - **知识点**:算法实现,H...
- **解析:** 这个题目主要考察字符串转换为数值类型的方法。 - `Double.parseDouble(s1)`将字符串`s1`转换为双精度浮点数`0.5`。 - `Integer.parseInt(s2)`将字符串`s2`转换为整数`12`。 - 最终输出`x + y`的结果...
在计算机科学与编程领域,设计一个能够处理包含括号的复杂表达式进行四则运算的计算器是一个常见的任务,这不仅考验了算法设计的能力,还涉及到字符串处理、数据类型转换等多个方面。本文将基于给定的Java代码片段,...
**知识点**:在编程语言中,经常需要进行字符串的拼接和转换操作。 - **chr(65)**:在许多编程语言中,chr函数用于将ASCII码转换为对应的字符,这里65对应的字符是“A”。 **结论**:执行命令?chr(65)+"K"的结果是...
- **字符串操作**:`String`类提供了一系列方法来进行字符串处理。 - 获取长度:`length()`。 - 字符串比较:`equals()`用于比较内容是否相等;`equalsIgnoreCase()`用于忽略大小写比较。 - 大小写转换:`...
字符串比较 **题目描述:** 结果为逻辑真的表达式是什么? **答案解析:** - **A. "ABC"$"AB"**:这是错误的。 - **B. "ABC"$"ABXCYZ"**:这是错误的。 - **C. "ABCYZ"$"BC"**:这是错误的。 - **D. "BC"$"CBAABC...
#### 四、编程题解析 **1. 编写程序,输出以下信息。** ```cpp #include using namespace std; int main() { cout , How are you?" ; cout , I am learning C++ Language." ; return 0; } ``` **2. 编写 C++ ...