给定一个公式字符串用java进行拆解并计算结果
需求很简单,给定一个字符串形式的公式规则,用java代码进行拆解,并能计算出结果。
♦考虑字符串中数字格式【整数、小数点】
♦考虑字符串中运算符【+-*/()】
♦考虑空格、运算规则【被0除】
以下是参考地址,里边有讨论部分的内容:
https://bbs.csdn.net/topics/380022283
下边是代码部分,可以作为一个工具类进行使用:
package test; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Stack; /**
* 给定公式字符串拆解计算
* @author kerala
*
*/
public class CalUtil { static final String symbol = "+-*/()"; //运算符
static final String[] priority = {"+-", "*/", "()"}; //运算符优先级 /**
* 运算符比较器
*/
static Comparator<String> comp = new Comparator<String>() {
public int compare(String s1, String s2) {
int n1=0, n2=0;
for (int i=0; i<priority.length; i++) {
if (priority[i].indexOf(s1) >= 0) {n1 = i;}
if (priority[i].indexOf(s2) >= 0) {n2 = i;}
}
return (n1 - n2);
}
}; /**
* 输入字符串公式,返回结果
* @param exp
* @return
* @throws Exception
*/
public static String getResultByStrCal(String exp) throws Exception{
List<String> list = analyze(exp); //中缀转后缀
double result = cacl(list); //计算结果
return String.format("%.2f", result);//%.2f\n解释:%f ——浮点型 .2 ——两位小数点 \n ——换行
} /**
* 分析算式
* @param exp
* @return
* @throws Exception
*/
public static List<String> analyze(String exp) throws Exception {
if (exp == null) {
throw new Exception ("illegal parameter.");
}
exp = exp.replaceAll("\\s*", ""); //去掉所有的空格(为了方便中间存在空格算合法) List<String> list = new ArrayList<String>();
Stack<String> sym = new Stack<String>(); StringBuilder buf = new StringBuilder();
for (char c : exp.toCharArray()) {
if (symbol.indexOf(c) >= 0) { //如果是运算符
if (buf.length() > 0) { //如果有操作数
String v = buf.toString();
if (! v.matches("\\d+([.]\\d+)?")) {
throw new Exception ("illegal varaible("+v+").");
}
list.add(v);
buf.delete(0, buf.length());
} if (c == '(') {
sym.push(String.valueOf(c));
} else if (c == ')') {
String last = "";
while (sym.size() > 0) {
last = sym.pop();
if (last.equals("(")) {
break;
} else {
list.add(last);
}
}
if (!"(".equals(last)) {
throw new Exception ("illigal express.");
}
} else if (sym.size() > 0) {
String s = String.valueOf(c);
String last = sym.peek();
if (last.equals("(") || comp.compare(s, last) > 0) {
sym.push(s);
} else {
last = sym.pop();
list.add(last);
sym.push(s);
}
} else {
sym.push(String.valueOf(c));
}
} else { //不是运算符则当作操作数(因为已经去除所有空格,这里不再需要判断空格)
buf.append(c);
}
} if (buf.length() > 0) {
list.add(buf.toString());
} while (sym.size() > 0) {
String last = sym.pop();
if ("()".indexOf(last) >= 0) {
throw new Exception ("illigal express.");
}
list.add(last);
} return list;
} /**
* 计算
* @param list
* @return
* @throws Exception
*/
public static double cacl(List<String> list) throws Exception {
Stack<Double> val = new Stack<Double>();
double result = 0;
while (list.size() > 0) {
String s = list.remove(0);
if (symbol.indexOf(s) >= 0) {
double d1 = val.pop();
double d2 = val.pop();
if ("+".equals(s)) {
result = d2 + d1;
} else if ("-".equals(s)) {
result = d2 - d1;
} else if ("*".equals(s)) {
result = d2 * d1;
} else if ("/".equals(s)) {
result = d2 / d1;
} else {
throw new Exception ("illigal symbol("+s+").");
}
val.push(result);
} else {
if (!s.matches("\\d+([.]\\d+)?")) {
throw new Exception ("illigal variable("+s+").");
}
val.push(Double.valueOf(s));
}
} return result;
} }
测试一下:
package test; /**
* 测试拆分字符串公式运算
* @author kerala
*
*/
public class TestCal { /**
* @param args
* @throws Exception
*/
public static void main(String[] args) { String exp = "2.5*0.4+(2*5)";
try {
String result = CalUtil.getResultByStrCal(exp);
System.out.printf(result);
} catch (Exception e) {
e.printStackTrace();
System.out.println("请输入正确计算公式");
} } }
目前测试了几个公式,都还正确,如果有问题,以后再补充!
给定一个公式字符串用java进行拆解并计算结果的更多相关文章
- 给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回
给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回 //统计字符串中出现的字符的出现次数 public function strNum(){ ...
- 给定一个字符串,根据字符出现频率排序--Java实现
题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...
- 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length
// 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba ...
- 数字使用相应的加密策略传递一个字符串后Java实现代码
公司采用公用电话传递数据,数据小于8整数位,为了确保安全, 在转移的过程中需要加密,加密规则如下面的: 第一个数据下降,附图然后各加5,和除以10的余数取代该数字, ...
- 给定一个字符串str,将str中连续两个字符为a的字符替换为b(一个或连续超过多个字符a则不替换)
需求:给定一个字符串str,将str中连续两个字符为a的字符替换为b(一个或连续超过多个字符a则不替换) 如: a 不替换 b 不替换 ab 不替换 ba 不替换 aba 不替换 aab 替换为 ...
- 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串
import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...
- JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )
题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...
- 给定一个字符串,仅由a,b,c 3种小写字母组成。
package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...
- 给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。
题目:给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后. 要求:空间复杂度是O(1),且 ...
随机推荐
- emlog博客的安装教程
简介 emlog 是一款基于PHP和MySQL的功能强大的博客及CMS建站系统.致力于为您提供快速.稳定,且在使用上又极其简单.舒适的内容创作及站点搭建服务. 安装步骤 1.将src文件夹下的所有文件 ...
- XMind使用教程入门
什么是思维导图 借用百度百科的介绍,思维导图又称脑图.心智导图.是一种将思维形象化的方法,它利用图文并重的方法,将各级主题之间的关系用相互隶属与相关的层级图表现出来,将主题关键词与图像.颜色等建立记忆 ...
- linux 网络基础之IP地址
IP是英文Internet Protocol的缩写,意思是“网络之间互连的协议”,也就是为计算机网络相互连接进行通信而设计的协议. IP地址类型分为:公有地址.私有地址. 公有地址 公有地址(Publ ...
- NLP(一)语料库和WordNet
访问语料库 NLTK数据库的安装:http://www.nltk.org/data.html NLTK语料库列表:http://www.nltk.org/nltk_data/ 内部访问(以Reuter ...
- 使用Python爬取淘宝两千款套套
各位同学们,好久没写原创技术文章了,最近有些忙,所以进度很慢,给大家道个歉. 警告:本教程仅用作学习交流,请勿用作商业盈利,违者后果自负!如本文有侵犯任何组织集团公司的隐私或利益,请告知联系猪哥删除! ...
- 洛谷P1939【模板】矩阵加速(数列)+矩阵快速幂
思路: 这个 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 可以想成: [a(n) ] [1 0 1] [a(n-1) ] [a(n-1) ] = ...
- 【百度之星】【思维】hdu 6724Totori's Switching Game
思维题,最后只要判断每个点的度数>=k即可. #pragma comment(linker, "/STACK:1024000000,1024000000") #pragma ...
- CodeForces 1082 F Speed Dial
题目传送门 题意:现在有n个电话号码,每个电话号码为si,拨打次数为pi. 现在有k 个快捷键,每次拨打号码之前可以先按一次快捷键,然后再输入数字,现在问输入数字次数是多少.快捷键的号码可以不在电话簿 ...
- JOBDU 1109 连通图
题目1109:连通图 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4192 解决:2224 题目描述: 给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的. 输入: 每组数据 ...
- Python---列表的学习(一)
本文将介绍列表和列表的使用: 我对列表的理解是和c,c++中的数组,vector,数据结构-链表-栈-队列,都很相似,因此列表很强大(相对于c,c++来说),所以在python的学习中列表是个重点. ...