program get error Exception in thread "main" java.lang.NumberFormatException: when iterate a math expression

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

program get error Exception in thread "main" java.lang.NumberFormatException: when iterate a math expression

问题

以下是翻译好的代码部分:

import java.util.Scanner;
import java.util.Stack;

public class Calculator {

    static Stack<Integer> stackForOperand = new Stack<Integer>();
    static Stack<Character> stackForOperator = new Stack<Character>();

    public static int processOneOperator(char operator, int num1, int num2) {
        int result = 0;

        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    throw new UnsupportedOperationException("divide by zero error");
                }
                break;
        }
        return result;
    }

    public static boolean num_order(char first, char second) {
        if (first == '(' || second == ')') {
            return false;
        } else if ((first == '*' || first == '/') && (second == '+' || second == '-')) {
            return false;
        } else {
            return true;
        }
    }

    public static int calculation_loop(String expression) {
        for (int i = 0; i < expression.length(); i++) {
            if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                String more_num = "";

                while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    more_num += expression.charAt(i++);
                    int more_num2 = Integer.parseInt(more_num);
                    stackForOperand.push(more_num2);
                    i--;
                }
            } else if (expression.charAt(i) == '(') {
                stackForOperator.push(expression.charAt(i));
            } else if (expression.charAt(i) == ')') {
                while (stackForOperator.peek() != '(') {
                    stackForOperand.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
                }
                stackForOperator.pop();
            } else if (expression.charAt(i) == '+' || expression.charAt(i) == '-' || expression.charAt(i) == '*' || expression.charAt(i) == '/') {
                while (!stackForOperator.empty() && num_order(expression.charAt(i), stackForOperator.peek())) {
                    stackForOperand.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
                }
                stackForOperator.push(expression.charAt(i));
            }
        }
        while (!stackForOperator.empty()) {
            stackForOperand.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
        }
        return stackForOperand.pop();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入表达式:");
        String input = scanner.nextLine();
        input = input.replaceAll("\\s+", "");

        System.out.println("输入的表达式:" + input);
        int output = calculation_loop(input);

        System.out.println("计算结果:" + output);
    }
}

注意:我已经对代码进行了翻译,但代码中可能仍存在其他潜在的逻辑问题,需要进一步检查和测试。

英文:

When I try to use the function to iterate the user input expression, I get the java.lang.NumberFormatException, I try fixing the loop much time, but I still cannot understand where did it when wrong. The IDE suggest it went wrong in the parstInt while loop

Here is the code:

import java.util.Scanner;
import java.util.Stack;
static Stack&lt;Integer&gt; stackForOperand = new Stack&lt;Integer&gt;();
static Stack&lt;Character&gt; stackForOperator = new Stack&lt;Character&gt;();
public static int processOneOperator(char stackForOperator, int num1, int num2) {
int result = 0;
switch (stackForOperator) {
case &#39;+&#39;:
result = num1 + num2;
case &#39;-&#39;:
result = num1 - num2;
case &#39;*&#39;:
result = num1 * num2;
case &#39;/&#39;:
if (num2 != 0) {
result = num1 / num2;
} else {
throw new UnsupportedOperationException(&quot;divide by zero error&quot;);
}
}
return result;
}
public static boolean num_order(char first, char second) {
if (first == &#39;(&#39; || second == &#39;)&#39;) {
return false;
} else if ((first == &#39;*&#39; || first == &#39;/&#39;) &amp;&amp; (second == &#39;+&#39; || second == &#39;-&#39;)) {
return false;
} else {
return true;
}
}
public static int calculation_loop(String expression) {
for (int i = 0; i &lt; expression.length(); i++) {
if (expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
String more_num = &quot;&quot;;
while (i &lt; expression.length() &amp;&amp; expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
more_num += expression.charAt(i++);
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
i--;
}
} else if (expression.charAt(i) == &#39;(&#39;) {
stackForOperator.push(expression.charAt(i));
} else if (expression.charAt(i) == &#39;)&#39;) {
while (stackForOperator.peek() != &#39;(&#39;) {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.pop();
}
} else if (expression.charAt(i) == &#39;+&#39; || expression.charAt(i) == &#39;-&#39; || expression.charAt(i) == &#39;*&#39;
|| expression.charAt(i) == &#39;/&#39;) {
while (!stackForOperator.empty() &amp;&amp; num_order(expression.charAt(i), stackForOperator.peek())) {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.push(expression.charAt(i));
}
}
}
while (!stackForOperator.empty()) {
stackForOperand
.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
}
return stackForOperand.pop();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println(&quot;/&quot;);
String input = scanner.nextLine();
input = input.replaceAll(&quot;\\s+&quot;, &quot;&quot;);
System.out.println(input);
Integer output = calculation_loop(input);
System.out.println(output);
}

}

答案1

得分: 1

看着这段代码:

    public static int calculation_loop(String expression) {

        for (int i = 0; i < expression.length(); i++) {

            if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                String more_num = "";

                while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    more_num += expression.charAt(i++);
                }
                int more_num2 = Integer.parseInt(more_num);
                stackForOperand.push(more_num2);

所以,假设有这样一个表达式 "2345+6789"。根据你的代码,i 在 while 循环结束之前会先递增然后递减。

              while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    more_num += expression.charAt(i++);
                    ...
                    i--;
                }

这是你的意图吗?这会导致你的循环变成无限循环,只会在解析时抛出数字格式异常才会结束。这就是我认为你的解析器抛出异常的原因:在第一个位置得到了数字 2,将其与 more_num 连接,然后递增 i,然后再递减 i,在下一次迭代中,你有了相同的前一个位置和相同的字符 2,然后将其再次连接到 more_num,无限循环下去。首先你解析了 more_num,它是 "2",在下一次迭代中你再添加一个 2,得到 more_num"22",然后是 "222"... 一直到它变得比 int 类型可以容纳的更大,像 "22222222222222222222222",然后抛出异常。

第二件事,假设你移除 i--,循环将正常迭代到下一个字符。这样,stackForOperand 将首先推入数字 2,然后将数字 23 推入,然后是数字 234,然后将数字 2345 推入。这是你的意图吗?我认为更合理的做法是将 Integer.parseIntstackForOperand.push 移动到 while 循环之后。

    public static int calculation_loop(String expression) {

        for (int i = 0; i < expression.length(); i++) {

            if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                String more_num = "";

                while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    more_num += expression.charAt(i++);
                }
                int more_num2 = Integer.parseInt(more_num);
                stackForOperand.push(more_num2);
英文:

Looking at this piece of code:

    public static int calculation_loop(String expression) {

        for (int i = 0; i &lt; expression.length(); i++) {

            if (expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
                String more_num = &quot;&quot;;

                while (i &lt; expression.length() &amp;&amp; expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
                    more_num += expression.charAt(i++);
                    int more_num2 = Integer.parseInt(more_num);
                    stackForOperand.push(more_num2);
                    i--;
                }

So. Suppose having such an expression &quot;2345+6789&quot;. According to your code i is incrementing and decrementing before end of while loop.

              while (i &lt; expression.length() &amp;&amp; expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
                    more_num += expression.charAt(i++);
                    ...
                    i--;
                }

Is this your intention? It makes your loop infinite and it finishes only because number format exception is thrown while parsing. This is why I think your parser throws exception: You got the digit &#39;2&#39; in first place, concatenate it with more_num, then increment the i, after that decrement the i and at the next iteration you have the same previous position with same char &#39;2&#39;, then concatenate it again to more_num ad infinitum. And first you parse more_num which is "2", on next iteration you append one more &#39;2&#39; and more_num "22" then "222"... Till it become bigger than type int can hold like "22222222222222222222222" and exception is thrown<br/>
Second thing. Suppose you remove i-- and your loop will normally iterate the next char. So, your stackForOperand will push first the number 2, then will push the number 23 then the number 234, then will push the number 2345. Is that your intension? I think more logically is to move Integer.parseInt and stackForOperand.push after the while loop<br/>

    public static int calculation_loop(String expression) {

        for (int i = 0; i &lt; expression.length(); i++) {

            if (expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
                String more_num = &quot;&quot;;

                while (i &lt; expression.length() &amp;&amp; expression.charAt(i) &gt;= &#39;0&#39; &amp;&amp; expression.charAt(i) &lt;= &#39;9&#39;) {
                    more_num += expression.charAt(i++);
                }
                int more_num2 = Integer.parseInt(more_num);
                stackForOperand.push(more_num2);

huangapple
  • 本文由 发表于 2020年10月13日 05:36:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64325646.html
匿名

发表评论

匿名网友

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

确定