代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
Java
】
四则混合带算式分析计算器
作者:
张林
/ 发布于
2011/1/10
/
889
四则混合计算器最麻烦的是什么? 是优先级的问题,那么括号就要匹配,算符左右要有表达式,这些都要判断。好了,这里有做的非常好的一个计算器示例
<div>/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package cn.siox.util.math;</div> import java.util.*; import java.util.regex.*; /** * * @author Lindily */ public class Calculate { public Vector<String> getExpression(String str) { Vector<String> v_temp = new Vector<String>(); char[] temp = new char[str.length()]; str.getChars(0, str.length(), temp, 0); String fi = ""; int x = 0, i = 0; String regex_fig = "[\\.\\d]"; // 匹配数字和小数点 String regex_operator = "[\\+\\-\\*/\\(\\)]"; //匹配运算符(+,-,*,/)和括号("(",")" // ) Pattern p_fig = Pattern.compile(regex_fig); Pattern p_operator = Pattern.compile(regex_operator); Matcher m = null; boolean b; while (i < str.length()) { Character c = new Character(temp[i]); String s = c.toString(); // System.out.println("char c = "+s); m = p_operator.matcher(s); b = m.matches();</div> <div> if (b) { // System.out.println("matches operator"); v_temp.add(fi); fi = ""; v_temp.add(s); } m = p_fig.matcher(s); b = m.matches(); if (b) { // System.out.println("matches fig"); fi = fi + s; } i++; } v_temp.add(fi);</div> <div> return v_temp; } <div> /** *转换中序表示式为前序表示式 * @param v_expression * @return */ public Vector<String> transformPrefix(Vector<String> v_expression) { Vector<String> v_prefix = new Vector<String>(); Stack<String> s_tmp = new Stack<String>(); String regex_float = "<a href="file://\\d+(\\.\\d">\\d+(\\.\\d</a>+)?"; // 匹配正浮点数 Pattern p_float = Pattern.compile(regex_float); Matcher m = null; boolean b; String str_elem = "";</div> <div> for (int i = 0; i < v_expression.size(); i++) { str_elem = v_expression.get(i).toString(); m = p_float.matcher(str_elem); b = m.matches();</div> <div> if (b) { v_prefix.add(str_elem); } <div> if (str_elem.equals("+") || str_elem.equals("-")) { if (s_tmp.isEmpty()) { s_tmp.push(str_elem); } else { while (!s_tmp.isEmpty()) { String str_tmp = s_tmp.peek();</div> <div> if (str_tmp.equals("(")) { break; } else { v_prefix.add(s_tmp.pop()); } } s_tmp.push(str_elem); } } <div> if (str_elem.equals("*") || str_elem.equals("/")) { if (s_tmp.isEmpty()) { s_tmp.push(str_elem); } else { while (!s_tmp.isEmpty()) { String str_tmp = s_tmp.peek();</div> <div> if (str_tmp.equals("(") || str_tmp.equals("+") || str_tmp.equals("-")) { break; } else { v_prefix.add(s_tmp.pop()); } } s_tmp.push(str_elem); } } <div> if (str_elem.equals("(")) { s_tmp.push(str_elem); } <div> if (str_elem.equals(")")) { while (!s_tmp.isEmpty()) { String str_tmp = s_tmp.peek(); if (str_tmp.equals("(")) { s_tmp.pop(); break; } else { v_prefix.add(s_tmp.pop()); } } } } <div> while (!s_tmp.isEmpty()) { v_prefix.add(s_tmp.pop()); } return v_prefix; } <div> /** * ;*前缀表示式求值 * @param v_prefix * @return double */ public strictfp double evaluatePrefix(Vector<String> v_prefix) { String str_tmp = ""; double num1, num2, interAns = 0; Stack<Double> s_compute = new Stack<Double>();</div> <div> int i = 0; while (i < v_prefix.size()) { str_tmp = v_prefix.get(i).toString(); if (!str_tmp.equals("+") && !str_tmp.equals("-") && !str_tmp.equals("*") && !str_tmp.equals("/")) { interAns = s_compute.push(Double.parseDouble(str_tmp)); } else { num2 = (Double) (s_compute.pop()); num1 = (Double) (s_compute.pop());</div> <div> if (str_tmp.equals("+")) { interAns = num1 + num2; } if (str_tmp.equals("-")) { interAns = num1 - num2; } if (str_tmp.equals("*")) { interAns = num1 * num2; } if (str_tmp.equals("/")) { interAns = num1 / num2; } s_compute.push(interAns); } i++; } return interAns; } <div> /** *括号匹配检测 * @param str * @return */ public boolean checkBracket(String str) { Stack<Character> s_check = new Stack<Character>(); boolean b_flag = true;</div> <div> for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); switch (ch) { case '(': s_check.push(ch); break; case ')': if (!s_check.isEmpty()) { char chx = s_check.pop(); if (ch == ')' && chx != '(') { b_flag = false; } } else { b_flag = false; } break; default: break; } } if (!s_check.isEmpty()) { b_flag = false; } return b_flag; } <div> /** *表达式正确性规则处理与校验 * @param str * @return */ public String checkExpression(String str) { Stack<Character> s_check = new Stack<Character>(); Stack<Character> s_tmp = new Stack<Character>(); String str_result = "";</div> <div> String str_regex = "^[\\.\\d\\+\\-\\*/\\(<a href="file://\\)]+$">\\)]+$</a>"; // 匹配合法的运算字符 // "数字,.,+,-,*,/,(,)," Pattern p_filtrate = Pattern.compile(str_regex); Matcher m = p_filtrate.matcher(str); boolean b_filtrate = m.matches(); if (!b_filtrate) { str_result = ""; return str_result; } <div> String str_err_float = ".*(<a href="file://\\.\\d*){2">\\.\\d*){2</a>,}.*"; // 匹配非法的浮点数. Pattern p_err_float = Pattern.compile(str_err_float); Matcher m_err_float = p_err_float.matcher(str); boolean b_err_float = m_err_float.matches(); if (b_err_float) { str_result = ""; return str_result; } <div> for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); if (checkFig(ch)) { if (!s_tmp.isEmpty() && s_tmp.peek() == ')') { str_result = ""; return str_result; } s_tmp.push(ch); str_result = str_result + ch; } <div> switch (ch) { case '(': if (!s_tmp.isEmpty() && s_tmp.peek() == '.') { str_result = ""; return str_result; } s_check.push(ch); if (s_tmp.isEmpty() || (!this.checkFig(s_tmp.peek()) && s_tmp.peek() != ')')) { str_result = str_result + ch; } else { str_result = str_result + "*" + ch; } s_tmp.push(ch); break; case ')': if (!s_check.isEmpty()) { char chx = s_check.pop(); if (ch == ')' && chx != '(') { str_result = ""; return str_result; } } else { str_result = ""; return str_result; } if (s_tmp.peek() == '.' || (!this.checkFig(s_tmp.peek()) && s_tmp.peek() != ')')) { str_result = ""; return str_result; } s_tmp.push(ch); str_result = str_result + ch; break; case '+': case '-': if (!s_tmp.isEmpty() && (s_tmp.peek() == '+' || s_tmp.peek() == '-' || s_tmp.peek() == '*' || s_tmp.peek() == '/' || s_tmp.peek() == '.')) { str_result = ""; return str_result; } if (s_tmp.isEmpty() || s_tmp.peek() == '(') { str_result = str_result + "0" + ch; } else { str_result = str_result + ch; } s_tmp.push(ch); break; case '*': case '/': if (s_tmp.isEmpty() || s_tmp.peek() == '.' || (!this.checkFig(s_tmp.peek()) && s_tmp.peek() != ')')) { str_result = ""; return str_result; } s_tmp.push(ch); str_result = str_result + ch; break; case '.': if (s_tmp.isEmpty() || !this.checkFig(s_tmp.peek())) { str_result = str_result + "0" + ch; } else { str_result = str_result + ch; } s_tmp.push(ch); break;</div> <div> default: break; } } if (!s_check.isEmpty()) { str_result = ""; return str_result; } <div> return str_result;</div> <div> } <div> /** * 数字校验 * @param ch * @return */ private static boolean checkFig(Object ch) { String s = ch.toString(); String str_regexfig = "<a href="file://\\d">\\d</a>"; // 匹配数字 Pattern p_fig = Pattern.compile(str_regexfig); Matcher m_fig = p_fig.matcher(s); boolean b_fig = m_fig.matches(); return b_fig; } <div> /** * 输入表达式 expression 计算结果,返回String * @param expression 表达式 * @return 结果字符串 */ protected String calculateResult(String expression) { String str_input = ""; double f_output; String temps=""; Calculate calculator = new Calculate(); str_input = calculator.checkExpression(expression); if (str_input.equals("")) { temps="error expression or result"; } else { Vector<String> v_compute = calculator.getExpression(str_input); Vector<String> v_tmp_prefix = calculator.transformPrefix(v_compute); f_output = calculator.evaluatePrefix(v_tmp_prefix); temps = expression+" = " + f_output; } return temps; } <div> //TEST public static void main(String[] args){ Calculate cal=new Calculate(); cal.calculateResult(args[0]); } }
试试其它关键字
计算器
同语言下
.
List 切割成几份 工具类
.
一行一行读取txt的内容
.
Java PDF转换成图片并输出给前台展示
.
java 多线程框架
.
double类型如果小数点后为零则显示整数否则保留两位小
.
将图片转换为Base64字符串公共类抽取
.
sqlParser 处理SQL(增删改查) 替换schema 用于多租户
.
JAVA 月份中的第几周处理 1-7属于第一周 依次类推 29-
.
java计算两个经纬度之间的距离
.
输入时间参数计算年龄
可能有用的
.
实现测量程序运行时间及cpu使用时间
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
张林
贡献的其它代码
(
1
)
.
四则混合带算式分析计算器
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3