需求很简单,给定一个字符串形式的公式规则,用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进行拆解并计算结果的更多相关文章

  1. 给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回

    给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回 //统计字符串中出现的字符的出现次数 public function strNum(){ ...

  2. 给定一个字符串,根据字符出现频率排序--Java实现

    题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...

  3. 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length

    // 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba ...

  4. 数字使用相应的加密策略传递一个字符串后Java实现代码

    公司采用公用电话传递数据,数据小于8整数位,为了确保安全,     在转移的过程中需要加密,加密规则如下面的:         第一个数据下降,附图然后各加5,和除以10的余数取代该数字,       ...

  5. 给定一个字符串str,将str中连续两个字符为a的字符替换为b(一个或连续超过多个字符a则不替换)

    需求:给定一个字符串str,将str中连续两个字符为a的字符替换为b(一个或连续超过多个字符a则不替换) 如: a 不替换 b 不替换  ab 不替换 ba 不替换 aba 不替换  aab 替换为 ...

  6. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,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, 字符串内的其他字 ...

  7. JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )

    题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...

  8. 给定一个字符串,仅由a,b,c 3种小写字母组成。

    package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...

  9. 给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。

    题目:给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后. 要求:空间复杂度是O(1),且 ...

随机推荐

  1. 2019年7-8月Leetcode每日训练日志

    2019-08-29 #274 H指数 2019-08-28 #287 寻找重复数 #875 爱吃香蕉的珂珂 #704 二分查找 2019-08-27 #744 寻找比目标字母大的最小字母 #225 ...

  2. spss分析存在共性线后,接下来是怎么分析?

    在进行线性回归分析时,容易出现自变量(解释变量)之间彼此相关,这种情况被称作多重共线性问题. 适度的多重共线性不成问题,但当出现严重共线性问题时,可能导致分析结果不稳定,出现回归系数的符号与实际情况完 ...

  3. TensorFlow Distribution(分布式中的数据读取和训练)

    本文目的 在介绍estimator分布式的时候,官方文档由于版本更新导致与接口不一致.具体是:在estimator分布式当中,使用dataset作为数据输入,在1.12版本中,数据训练只是datase ...

  4. HDU-4027-Can you answer these queries?线段树+区间根号+剪枝

    传送门Can you answer these queries? 题意:线段树,只是区间修改变成 把每个点的值开根号: 思路:对[X,Y]的值开根号,由于最大为 263.可以观察到最多开根号7次即为1 ...

  5. 2019 Multi-University Training Contest 5

    2019 Multi-University Training Contest 5 A. fraction upsolved 题意 输入 \(x,p\),输出最小的 \(b\) 使得 \(bx\%p&l ...

  6. Different Integers 牛客网暑期ACM多校训练营(第一场) J 离线+线状数组或者主席树

    Given a sequence of integers a1, a2, ..., an and q pairs of integers (l 1, r1), (l2, r2), ..., (lq, ...

  7. 面试加分项-HashMap源码中这些常量的设计目的

    前言 之前周会技术分享,一位同事讲解了HashMap的源码,涉及到一些常量设计的目的,本文将谈谈这些常量为何这样设计,希望大家有所收获. HashMap默认初始化大小为什么是1 << 4( ...

  8. 在windows上,使用虚拟机安装苹果操作系统

    以下是我这两天安装这个苹果操作系统时,所看的文档,集合.已经成功,再次做一个摘录. 分别看了一下几个链接: http://www.bubuko.com/infodetail-2257390.html ...

  9. 实现一个基于码云的Storage

    实现一个简单的基于码云(Gitee) 的 Storage Intro 上次在 asp.net core 从单机到集群 一文中提到存储还不支持分布式,并立了一个 flag 基于 github 或者 开源 ...

  10. java第一次测验

    package kaoshi; import java.util.Scanner; public class ScoreManagement { static int t=0; static int ...