java实现科学计算器

实现科学计算器:

就要想它的算法,这里应用的是经典的后缀表达式的应用。

后缀表达式:

一种不需要括号的后缀表达法,

如:1+2*3*(1+2)+(3-2)*(5/2) 为中缀表达法;

它所对应的后缀表达式为:123*12+*+32-52/*+ 

中缀表达式转后缀表达式:

可以用栈进行入算术符进行转换,

然后进行优先级的判断,进行出入栈的操作;

后缀表达式计算结果:

遍历后缀表达式,遇到数字进行入栈,遇到符号弹出2个数进行计算,再次入栈。

下面试java的实现代码:


 
 
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Scanner;
  4. import java.util.Stack;
  5. /**
  6. * 科学表达式: 总的计算思路为:
  7. 1.将中缀表达式转化为后缀表达式(栈是用来进出运算的符号)
  8. 2.将后缀表达式进行运算得出结果(栈是用来进出运算的数字)
  9. *
  10. * @author chennan
  11. *
  12. */
  13. public class Calculate {
  14. public static void main(String[] args) {
  15. Scanner sc= new Scanner(System.in);
  16. System.out.println( "请输入一个包含加减乘除的表达式:");
  17. String s=sc.nextLine();
  18. System.out.println(s+ "="+calculate(s));
  19. }
  20. public static double calculate(String expre) {
  21. List<String> num=transformEnd(expre);
  22. Stack<Double> stack = new Stack<>();
  23. double sum = 0;
  24. while (!num.isEmpty()) {
  25. String temp = String.valueOf(num.remove( 0));
  26. if (isNamber(temp)) {
  27. double s=Double.parseDouble(temp);
  28. stack.push(s);
  29. } else {
  30. double a=stack.pop();
  31. double b=stack.pop();
  32. double c=calTwo(b,a,temp);
  33. stack.push(c);
  34. }
  35. }
  36. sum=stack.pop();
  37. return sum;
  38. }
  39. private static double calTwo(double a, double b, String opr) {
  40. double sum = 0;
  41. switch (opr) {
  42. case "+":
  43. sum = a + b;
  44. break;
  45. case "-":
  46. sum = a - b;
  47. break;
  48. case "*":
  49. sum = a * b;
  50. break;
  51. case "/":
  52. sum = a / b;
  53. break;
  54. }
  55. return sum;
  56. }
  57. /**
  58. *
  59. * 1.将中缀表达式转化为后缀表达式(栈是用来进出运算的符号)
  60. */
  61. public static List<String> transformEnd(String expre) {
  62. List<String> sb = new ArrayList<>();
  63. Stack<String> stack = new Stack<>();
  64. expre = expre.replaceAll( "(\\D)", "o$1o");
  65. String[] esp = expre.trim().split( "o");
  66. for ( int i = 0; i < esp.length; i++) {
  67. String s = esp[i].trim();
  68. if (isNamber(s)) {
  69. // 如果是数字则输出
  70. sb.add(s);
  71. } else if (!s.isEmpty()) {
  72. if (s.charAt( 0) == ')') {
  73. while (stack.peek().charAt( 0) != '(') {
  74. sb.add(stack.pop());
  75. }
  76. stack.pop();
  77. } else {
  78. if (!stack.isEmpty() && !isMaxExp(s.charAt( 0), stack.peek().charAt( 0))) {
  79. while (!stack.isEmpty() && !isMaxExp(s.charAt( 0), stack.peek().charAt( 0))) {
  80. sb.add(stack.pop());
  81. }
  82. stack.push(s);
  83. } else {
  84. stack.push(s);
  85. }
  86. }
  87. }
  88. }
  89. while (!stack.isEmpty()) {
  90. sb.add(stack.pop());
  91. }
  92. return sb;
  93. }
  94. // 判断是否是数字
  95. private static boolean isNamber(String str) {
  96. try {
  97. Double.parseDouble(str);
  98. } catch (RuntimeException e) {
  99. return false;
  100. }
  101. ;
  102. return true;
  103. }
  104. // 判断是否进栈
  105. private static boolean isMaxExp(char exp1, char exp2) {
  106. if (exp1 == '(')
  107. return true;
  108. if (exp2 == ')')
  109. return true;
  110. if (transExp(exp1) > transExp(exp2))
  111. return true;
  112. return false;
  113. }
  114. private static int transExp(char exp) {
  115. int re = 0;
  116. switch (exp) {
  117. case '*':
  118. case '/':
  119. re = 2;
  120. break;
  121. case '+':
  122. case '-':
  123. re = 1;
  124. break;
  125. }
  126. return re;
  127. }
  128. }

 

  • 转载地址:https://blog.csdn.net/qq_39456707/article/details/82690892
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值