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

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

Alternative way to replace Nested While Loop in Java

问题

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

public double applyOp(char op, double b, double a) {
    switch (op) {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            return a / b;
    }
    return 0;
}

public boolean hasPrecedence(char op1, char op2) {
    return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
}

public double evaluate(String input) {
    Stack<Double> values = new Stack<>();
    Stack<Character> ops = new Stack<>();
    int stringIndex = 0;

    while (stringIndex < input.length()) {
        StringBuilder multiDigitsNumber = new StringBuilder();

        // If the input is a number, put it onto the values stack
        if (input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9') {
            while (stringIndex < input.length() && input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9') {
                multiDigitsNumber.append(input.charAt(stringIndex++));
            }
            values.push(Double.parseDouble(multiDigitsNumber.toString()));
        }

        // If the input is an operator, put it onto the ops stack
        else {
            while (!ops.empty() && hasPrecedence(input.charAt(stringIndex), ops.peek())) {
                values.push(applyOp(ops.pop(), values.pop(), values.pop()));
            }
            ops.push(input.charAt(stringIndex++));
        }
    }

    // Execute remaining operators in the values stack
    while (!ops.empty()) {
        values.push(applyOp(ops.pop(), values.pop(), values.pop()));
    }

    // The final number in the values stack is the result
    return values.pop();
}

Input example:

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

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

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

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

英文:

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

public double applyOp(char op,double b,double a)
{
switch (op)
{
case &#39;+&#39;:
return a + b;
case &#39;-&#39;:
return a - b;
case &#39;*&#39;:
return a * b;
case &#39;/&#39;:
return a / b;
}
return 0;
}
public boolean hasPrecedence(char op1,char op2)
{
return (op1 != &#39;*&#39; &amp;&amp; op1 != &#39;/&#39;) || (op2 != &#39;+&#39; &amp;&amp; op2 != &#39;-&#39;);
}
public double evaluate(String input) {
Stack&lt;Double&gt; values = new Stack&lt;&gt;();
Stack&lt;Character&gt; ops = new Stack&lt;&gt;();
int stringIndex = 0;
while (stringIndex &lt; input.length())
{
StringBuilder multiDigitsNumber = new StringBuilder();
// If the input is number put to stack values
if (input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
{
while (stringIndex &lt; input.length() &amp;&amp; input.charAt(stringIndex) &gt;= &#39;0&#39; &amp;&amp; input.charAt(stringIndex) &lt;= &#39;9&#39;)
{
multiDigitsNumber.append(input.charAt(stringIndex++));
}
values.push(Double.parseDouble(multiDigitsNumber.toString()));
}
// If the input is operator put to stack ops
else
{
while (!ops.empty() &amp;&amp; hasPrecedence(input.charAt(stringIndex),ops.peek()))
{
values.push(applyOp(ops.pop(),values.pop(),values.pop()));
}
ops.push(input.charAt(stringIndex++));
}
}
// Execute remain operator in stack values
while (!ops.empty()) {
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
}
// The final number in stack value is result
return values.pop();
}

Input example:

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

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

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

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)。

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

You can use Regex like this.

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

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:

确定