当前位置:   article > 正文

Java算法题 给一个字符串表达式,实现一个基本计算器,返回计算结果_java计算字符串表达式

java计算字符串表达式

题目:

描述
给定一个字符串描述的算术表达式,计算出结果值。
输入字符串长度不超过 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。

数据范围:运算过程中和最终结果均满足∣val∣≤2^31−1  ,即只进行整型运算,确保输入的表达式合法
        输入描述:
        输入算术表达式

        输出描述:
        计算出结果值

        示例1
        输入:
        400+5
        复制
        输出:
        405

考点:栈

解题思路:

使用 2 个栈,一个 stack_nums 用来保存计算过程的操作数,一个 stack_symbol 用来保存运算符。

在HashMap中,指定加减优先级为1,乘除优先级为2

循环遍历字符串s,

  1. 操作符入栈:

    若当前字符为'+', '-', '*', '/', '(' 时,压入运算符栈 stack_symbol,

  2. 操作数入栈:

    若当前字符为数值类型,相当于循环读取字符串转化为十进制整数,直到下一个字符为非数值类型,把它压入操作数栈中。

  3. 执行运算:

    当遍历到加减乘除运算符时,判断栈stack_symbol内存在优先级大于等于当前运算符,则可以先执行一次运算,尽可能先消费栈stack_symbol内的运算符;

    当右括号出现时需要执行一次优先级运算,并从操作符栈内弹出对应的左括号;

  4. 运算规则:栈是后进先出,参与加减乘除运算时,第一个从 stack_nums 栈顶弹出的数应在运算符后面,第二个 stack_nums 从栈顶弹出的数应在运算符前面。

  1. 特殊情况处理:

  • 括号的处理:

括号有2种情况,

第一种是负数携带的括号,即除了第一个位置出现的数外,后面的数为负数时所附带的括号,

第二种是,需要优先进行运算的式子

  • 负数的处理:

对于负数的处理,增加一步 0 - n 运算,假设负号后面的数等于 n

开头第一个数带 '-' 号,s.charAt(0) == '-'

s = "0" + s;

或者括号 () 里面第一个数带 '-' 号,

s = s.replace( "(-", "(0-" );

认为是负号,否则认为是减号

当循环结束时,若栈stack_symbol内还有运算符,继续算完

  1. import java.util.Scanner;
  2. import java.util.Stack;
  3. import java.util.Map;
  4. import java.util.HashMap;
  5. // 注意类名必须为 Main, 不要有任何 package xxx 信息
  6. /**
  7. * @ClassName
  8. * @Description
  9. * @Author liulvhua
  10. * @Date 2023/4/5
  11. **/
  12. public class HJ54 {
  13. public static void main(String[] args) {
  14. Scanner sc = new Scanner(System.in);
  15. Stack<Integer> stack_nums = new Stack<>();
  16. Stack<Character> stack_symbol = new Stack<>();
  17. Map<Character, Integer> map = new HashMap<>();
  18. map.put('+', 1);
  19. map.put('-', 1);
  20. map.put('*', 2);
  21. map.put('/', 2);
  22. while (sc.hasNextLine()) {
  23. String s = sc.nextLine();
  24. if (s.charAt(0) == '-') {//第一个数为负数
  25. s = "0" + s;
  26. }
  27. s = s.replace("(-", "(0-");//其他位置负数处理
  28. for (int i = 0; i < s.length(); i++) {
  29. char ch = s.charAt(i);
  30. if (ch == ' ') continue;
  31. if (ch == '(') {
  32. stack_symbol.push(ch);
  33. continue;
  34. }
  35. if (ch == ')') {
  36. //括号结束计算一次
  37. stack_nums.push(calculate(stack_nums, stack_symbol));
  38. if (!stack_symbol.isEmpty() && stack_symbol.peek() == '(') {
  39. //当前计算是括号内最后一次运算,弹出左括号
  40. stack_symbol.pop();
  41. }
  42. continue;
  43. }
  44. if (map.containsKey(ch)) {
  45. // 栈内至少有1个运算符且栈顶不是左括号,并且栈内运算符优先级大于等于当前运算符号优先级,执行一次计算,
  46. // 即先消费已入栈的高优先级运算符
  47. while (!stack_symbol.isEmpty() && stack_symbol.peek() != '(' && map.get(stack_symbol.peek()) >= map.get(ch)) {
  48. stack_nums.push(calculate(stack_nums, stack_symbol));
  49. }
  50. stack_symbol.push(ch);
  51. } else {
  52. int num = 0;
  53. int j = i;//循环读取十进制整数
  54. while (j < s.length() && Character.isDigit(s.charAt(j))) {
  55. num = num * 10 + s.charAt(j) - '0';
  56. j++;
  57. }
  58. stack_nums.push(num);
  59. i = j - 1;
  60. }
  61. }
  62. // 循环结束还有未算尽的式子,优先级低
  63. while (!stack_symbol.isEmpty()) {
  64. stack_nums.push(calculate(stack_nums, stack_symbol));
  65. if (!stack_symbol.isEmpty() && stack_symbol.peek() == '(') {
  66. stack_symbol.pop();
  67. }
  68. }
  69. System.out.println(stack_nums.pop());
  70. }
  71. }
  72. /**
  73. * 执行运算
  74. * @param stack_nums 操作数栈
  75. * @param stack_symbol 运算符栈
  76. * @return
  77. */
  78. public static int calculate(Stack<Integer> stack_nums, Stack<Character> stack_symbol) {
  79. int res = 0;
  80. int opt_nums2 = stack_nums.pop();
  81. int opt_nums1 = stack_nums.pop();
  82. char symbol = stack_symbol.pop();
  83. switch (symbol) {
  84. case '+': {
  85. res = opt_nums1 + opt_nums2;
  86. break;
  87. }
  88. case '-': {
  89. res = opt_nums1 - opt_nums2;
  90. break;
  91. }
  92. case '*': {
  93. res = opt_nums1 * opt_nums2;
  94. break;
  95. }
  96. case '/': {
  97. res = opt_nums1 / opt_nums2;
  98. break;
  99. }
  100. }
  101. return res;
  102. }
  103. }

执行用例:

2*3-2*(1-2*2)-0
12
2*3-2*(1-2*(1-3))-0
-4
2*3-2*(1-2*(1-3))-0
-4
2*3-2*(1-2*(1-3)*(-1))-0
12 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/848196
推荐阅读
相关标签
  

闽ICP备14008679号