替代Java中嵌套While循环的方法

huangapple go评论101阅读模式
英文:

Alternative way to replace Nested While Loop in Java

问题

我尝试在Java中使用以下代码计算数学表达式:

  1. public double applyOp(char op, double b, double a) {
  2. switch (op) {
  3. case '+':
  4. return a + b;
  5. case '-':
  6. return a - b;
  7. case '*':
  8. return a * b;
  9. case '/':
  10. return a / b;
  11. }
  12. return 0;
  13. }
  14. public boolean hasPrecedence(char op1, char op2) {
  15. return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
  16. }
  17. public double evaluate(String input) {
  18. Stack<Double> values = new Stack<>();
  19. Stack<Character> ops = new Stack<>();
  20. int stringIndex = 0;
  21. while (stringIndex < input.length()) {
  22. StringBuilder multiDigitsNumber = new StringBuilder();
  23. // If the input is a number, put it onto the values stack
  24. if (input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9') {
  25. while (stringIndex < input.length() && input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9') {
  26. multiDigitsNumber.append(input.charAt(stringIndex++));
  27. }
  28. values.push(Double.parseDouble(multiDigitsNumber.toString()));
  29. }
  30. // If the input is an operator, put it onto the ops stack
  31. else {
  32. while (!ops.empty() && hasPrecedence(input.charAt(stringIndex), ops.peek())) {
  33. values.push(applyOp(ops.pop(), values.pop(), values.pop()));
  34. }
  35. ops.push(input.charAt(stringIndex++));
  36. }
  37. }
  38. // Execute remaining operators in the values stack
  39. while (!ops.empty()) {
  40. values.push(applyOp(ops.pop(), values.pop(), values.pop()));
  41. }
  42. // The final number in the values stack is the result
  43. return values.pop();
  44. }
  45. Input example:
  46. > 12+24*2-30/5.....

上述代码正常工作,但我想知道是否有方法可以替代下面这部分:

  1. while (stringIndex < input.length() && input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9') {
  2. multiDigitsNumber.append(input.charAt(stringIndex++));
  3. }

以避免在这种情况下使用嵌套的 while 循环。目标是在字符串中捕获数字,直到遇到运算符。提前感谢您的帮助。

英文:

I tried to Evaluate Mathematical Expressions in Java with the following code:

  1. public double applyOp(char op,double b,double a)
  2. {
  3. switch (op)
  4. {
  5. case &#39;+&#39;:
  6. return a + b;
  7. case &#39;-&#39;:
  8. return a - b;
  9. case &#39;*&#39;:
  10. return a * b;
  11. case &#39;/&#39;:
  12. return a / b;
  13. }
  14. return 0;
  15. }
  16. public boolean hasPrecedence(char op1,char op2)
  17. {
  18. return (op1 != &#39;*&#39; &amp;&amp; op1 != &#39;/&#39;) || (op2 != &#39;+&#39; &amp;&amp; op2 != &#39;-&#39;);
  19. }
  20. public double evaluate(String input) {
  21. Stack&lt;Double&gt; values = new Stack&lt;&gt;();
  22. Stack&lt;Character&gt; ops = new Stack&lt;&gt;();
  23. int stringIndex = 0;
  24. while (stringIndex &lt; input.length())
  25. {
  26. StringBuilder multiDigitsNumber = new StringBuilder();
  27. // If the input is number put to stack values
  28. if (input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
  29. {
  30. while (stringIndex &lt; input.length() &amp;&amp; input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
  31. {
  32. multiDigitsNumber.append(input.charAt(stringIndex++));
  33. }
  34. values.push(Double.parseDouble(multiDigitsNumber.toString()));
  35. }
  36. // If the input is operator put to stack ops
  37. else
  38. {
  39. while (!ops.empty() &amp;&amp; hasPrecedence(input.charAt(stringIndex),ops.peek()))
  40. {
  41. values.push(applyOp(ops.pop(),values.pop(),values.pop()));
  42. }
  43. ops.push(input.charAt(stringIndex++));
  44. }
  45. }
  46. // Execute remain operator in stack values
  47. while (!ops.empty()) {
  48. values.push(applyOp(ops.pop(), values.pop(), values.pop()));
  49. }
  50. // The final number in stack value is result
  51. return values.pop();
  52. }

Input example:

> 12+24*2-30/5.....

The code above works fine but I wonder are there any way to replace

  1. while (stringIndex &lt; input.length() &amp;&amp; input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
  2. {
  3. multiDigitsNumber.append(input.charAt(stringIndex++));
  4. }

with something else so I don't have to use nested while loop in this situation. The goal is to catch number in string until it reach an operator
Thanks in advance

答案1

得分: 1

可以像这样使用正则表达式(Regex)。

  1. if (input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9')
  2. {
  3. String number = input.substring(stringIndex).replaceAll("^(\\d+).*", "$1");
  4. values.push(Double.parseDouble(number));
  5. stringIndex += number.length();
  6. }
英文:

You can use Regex like this.

  1. if (input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
  2. {
  3. String number = input.substring(stringIndex).replaceAll(&quot;^(\\d+).*&quot;, &quot;$1&quot;);
  4. values.push(Double.parseDouble(number));
  5. stringIndex += number.length();
  6. }

huangapple
  • 本文由 发表于 2020年8月27日 11:55:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63608924.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定