做网站找哪个部门,长春网站制作优势吉网传媒,免版权图片网站,网站建设公司推目标#xff1a;最近想写个东西#xff0c;本质就是一个计算器#xff0c;我们可以输入公式#xff08;例如#xff1a;ab#xff09;#xff0c;然后把公式的值#xff08;a:10,b:20#xff09;也输入进去。最后得到结果。核心#xff1a;这个想法核心部分就是给一个…目标最近想写个东西本质就是一个计算器我们可以输入公式例如ab然后把公式的值a:10,b:20也输入进去。最后得到结果。核心这个想法核心部分就是给一个公式然后计算其结果。这个在网上有很多。比如我就参考的这个大佬的。附链接。 其核心思想就是用两个栈一次记录操作数一个值。链接中的方案数已经在字符串中了。然后需要找到这个数。我想要的是数在一个map中直接get出来就好了。此外计算过程中需要对减号特殊处理因为这个减号可能表示这个数是要取反的。代码中我直接在数栈和运算符栈中分别加入了-1和乘号实现的。
java核心代码
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Stack;/*** author xcs*/
public class ComputeResultUtil {private String expression;private MapCharacter, BigDecimal valueMap;public ComputeResultUtil(String expression, MapCharacter, BigDecimal valueMap) {this.expression expression;this.valueMap valueMap;}public BigDecimal compute() {StackBigDecimal nums new Stack();StackCharacter ops new Stack();//记录是否需要把 - 作为 负数存储boolean isOperatorPre false;for (int i 0; i expression.length(); i) {char c expression.charAt(i);if (Character.isAlphabetic(c)) {isOperatorPre false;nums.push(valueMap.get(c));} else if (c () {isOperatorPre true;ops.push(c);} else if (c )) {// 计算括号中的内容直到遇到左括号while (ops.peek() ! () {isOperatorPre false;nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}// 有括号也出栈ops.pop();} else if (isOperator(c)) {if (c - (isOperatorPre || ops.empty())) {nums.push(new BigDecimal(-1));ops.push(*);isOperatorPre false;} else {while (!ops.empty() needCalculatePre(c, ops.peek())) {nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}isOperatorPre true;ops.push(c);}}}while (!ops.empty()) {nums.push(calculateByOps(ops.pop(), nums.pop(), nums.pop()));}return nums.pop();}private static boolean isOperator(char c) {return c || c - || c * || c /;}private static boolean needCalculatePre(char op1, char op2) {if (op2 ( || op2 )) {return false;}return (op2 * || op2 /) (op1 || op1 -) || (op2 || op2 -) (op1 || op1 -);}private static BigDecimal calculateByOps(char op, BigDecimal b, BigDecimal a) {switch (op) {case :return a.add(b);case -:return a.subtract(b);case *:return a.multiply(b).setScale(4, BigDecimal.ROUND_HALF_UP);case /:if (b.compareTo(BigDecimal.ZERO) 0) {throw new UnsupportedOperationException(Cannot divide by zero);}return a.divide(b, 4, RoundingMode.HALF_UP);default:throw new UnsupportedOperationException(Unknown operator op);}}
}
使用方代码
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;/*** author xcs*/
public class ComputeResultMain {public static void main(String[] args) {System.out.print(输入公式公式中的变量目前只支持单字符);Scanner sc new Scanner(System.in);String formula sc.nextLine();System.out.println(输入公式中的变量值例如a:123空行表示结束);MapCharacter, BigDecimal valueMap new HashMap();while (true) {String value sc.nextLine();if (value.trim().isEmpty()) {break; // 空行作为结束标志}String[] split value.split([:]);valueMap.put(split[0].charAt(0), new BigDecimal(split[1]));}ComputeResultUtil computeResult new ComputeResultUtil(formula, valueMap);System.out.println(计算结果为 computeResult.compute());}
}收获 首先就是这个计算的过程上学的时候应该是学过的但是基本都忘了也是实在懒得写就直接百度了再次看下也算是学习了。其次我也是第一次知道string.split(“[:]”)的写法其含义是中文冒号和英文冒号拆分字符串。这种写法由于中括号中两个冒号中间没有拆分所以适用于单字符。如果是多字符的可以这样写.split(“字符1|字符2…”)例如1###2##3.split(“###|##”)拆分结果是123。需要注意的是其实现步骤可以理解为依次进行了两次拆分但是拆分结果放在一个数组中。可以看下面两个图一个1###2##3.split(“###|##”)一个是1###2##3.split(“##|###”)后者出现了#2的数据这是因为后者先使用##进行拆分。