运行 带有正则表达式的计算器程序时出现 NumberFormatException
NumberFormatException when running a calculator program with regular expression
我正在尝试编写一个简单的计算器。
public static String cal(){
String a="-60-1+40";
if(a.matches("-?[1-9][0-9]?([\+-][1-9][0-9]?)+")){
System.out.println(a);
String operators[]=a.split("[0-9]+");
String operands[]=a.split("[+-]");
int agregate = Integer.parseInt(operands[0]);
for(int i=1;i<operands.length;i++){
if(operators[i].equals("+"))
agregate += Integer.parseInt(operands[i]);
else
agregate -= Integer.parseInt(operands[i]);
}
return Integer.toString(agregate);
}else throw new invalidExpressionException(a+" is a Invalid expression");
}
我有这个功能,但是当我尝试 运行 它时,如果字符串的第一个字符是 "-"
,我会得到 NumberFormatException
。所有其他情况似乎都是正确的,只有那个失败了。我已经尝试修复了一段时间,但我不知道如何修复。
run:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
-60-1+40
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:592)
at java.lang.Integer.parseInt(Integer.java:615)
at calculator.Calculator.cal(Calculator.java:20)
at calculator.Calculator.main(Calculator.java:9)
试试这个..
public static String calculator(){
String a="-60-1+40";
if(a.matches("-?[1-9][0-9]?([\+-][1-9][0-9]?)+")){
System.out.println(a);
String operators[]=a.split("[0-9]+");
String operands[]=a.split("[+-]");
int agregate = operands[0].isEmpty() ? 0 : Integer.parseInt(operands[0]);//changed code
for(int i=1;i<operators.length;i++){//operators.length is better
if(operators[i].equals("+"))
agregate += Integer.parseInt(operands[i]);
else
agregate -= Integer.parseInt(operands[i]);
}
return Integer.toString(agregate);
}
return a;
}
根据@Ben 的评论,解决方法是检查第一个字符是否为“-
”,在这种情况下,在处理字符串之前将 0
添加到字符串中(-n可以从 0 中减去数字 n):
-1+2-3
,应该变成0-1+2-3
if(a.startsWith("-")){
a = "0" + a;
}
简答
简短的回答是您可以像这样过滤掉空字符串。 Streams 相对较新 API 并且编写它们可能很棘手。但是,我相信它们很容易阅读。所以这里是:
String operands[] = Arrays.stream(calculateCommand.split("[+-]"))
.filter(str -> str != null && 0 < str.trim().length()) // skipping the empty elements
.toArray(String[]::new);
拖钓答案
public static String cal() {
String a = "-60-1+40"; // a reminder for the developer
return "-21"; // a correct answer for the input above
}
这里有一个拖钓答案。只要函数总是returns不变,就可以直接用这个快捷方式:
返工
None 上面的修复程序可以满足您的需求。我放弃了修正那个方法。相反,我写了另一个函数:
// letting the reader know that this calculator can deal with + and - only
public static String additiveCalculator(String calculateCommand) {
if (calculateCommand == null) {
// input handling
throw new NullPointerException("cannot calculate null string");
}
if (calculateCommand.startsWith("-")) {
// dealing with only one case
return additiveCalculator("0" + calculateCommand);
}
if (! calculateCommand.matches("\d+(\s*[+-]\s*\d+)*")) {
throw new IllegalArgumentException("Input '" + calculateCommand + "' is not calculable.");
}
Integer[] operands = Arrays.stream(calculateCommand.split("[+-]"))
.map(str -> str.trim())
.map(str -> Integer.parseInt(str))
.toArray(Integer[]::new);
String[] operators = calculateCommand.replaceAll("[^+-]", "").split("");
int aggregate = operands[0];
for (int i = 0; i < operators.length; i++) {
int num = operands[i+1];
String op = operators[i];
switch (op) {
case "+":
aggregate += num;
break;
case "-":
aggregate -= num;
break;
default:
// this can't happen. However, later this exception might be useful
throw new IllegalStateException("The " + i + "th operator, '" + op + "' is not an additive operator.");
}
}
return Integer.toString(aggregate);
}
我添加了评论以指出改进之处。不过,我想解释一下数字检查器正则表达式。这是 \d+(\s*[+-]\s*\d+)*
。解释如下:
\d
代表数字。相当于 [0-9]
\s
代表空格。
\d+
正则表达式以数字开头,也可以为零。不需要添加 ^
因为我们使用 String.matches()
.
(...)*
那么我们可以看到零个或多个:
\s*[+-]\s*\d+
- 一些空格,一个运算符,一些空格,然后是一个数字
我正在尝试编写一个简单的计算器。
public static String cal(){
String a="-60-1+40";
if(a.matches("-?[1-9][0-9]?([\+-][1-9][0-9]?)+")){
System.out.println(a);
String operators[]=a.split("[0-9]+");
String operands[]=a.split("[+-]");
int agregate = Integer.parseInt(operands[0]);
for(int i=1;i<operands.length;i++){
if(operators[i].equals("+"))
agregate += Integer.parseInt(operands[i]);
else
agregate -= Integer.parseInt(operands[i]);
}
return Integer.toString(agregate);
}else throw new invalidExpressionException(a+" is a Invalid expression");
}
我有这个功能,但是当我尝试 运行 它时,如果字符串的第一个字符是 "-"
,我会得到 NumberFormatException
。所有其他情况似乎都是正确的,只有那个失败了。我已经尝试修复了一段时间,但我不知道如何修复。
run:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
-60-1+40
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:592)
at java.lang.Integer.parseInt(Integer.java:615)
at calculator.Calculator.cal(Calculator.java:20)
at calculator.Calculator.main(Calculator.java:9)
试试这个..
public static String calculator(){
String a="-60-1+40";
if(a.matches("-?[1-9][0-9]?([\+-][1-9][0-9]?)+")){
System.out.println(a);
String operators[]=a.split("[0-9]+");
String operands[]=a.split("[+-]");
int agregate = operands[0].isEmpty() ? 0 : Integer.parseInt(operands[0]);//changed code
for(int i=1;i<operators.length;i++){//operators.length is better
if(operators[i].equals("+"))
agregate += Integer.parseInt(operands[i]);
else
agregate -= Integer.parseInt(operands[i]);
}
return Integer.toString(agregate);
}
return a;
}
根据@Ben 的评论,解决方法是检查第一个字符是否为“-
”,在这种情况下,在处理字符串之前将 0
添加到字符串中(-n可以从 0 中减去数字 n):
-1+2-3
,应该变成0-1+2-3
if(a.startsWith("-")){
a = "0" + a;
}
简答
简短的回答是您可以像这样过滤掉空字符串。 Streams 相对较新 API 并且编写它们可能很棘手。但是,我相信它们很容易阅读。所以这里是:
String operands[] = Arrays.stream(calculateCommand.split("[+-]"))
.filter(str -> str != null && 0 < str.trim().length()) // skipping the empty elements
.toArray(String[]::new);
拖钓答案
public static String cal() {
String a = "-60-1+40"; // a reminder for the developer
return "-21"; // a correct answer for the input above
}
这里有一个拖钓答案。只要函数总是returns不变,就可以直接用这个快捷方式:
返工
None 上面的修复程序可以满足您的需求。我放弃了修正那个方法。相反,我写了另一个函数:
// letting the reader know that this calculator can deal with + and - only
public static String additiveCalculator(String calculateCommand) {
if (calculateCommand == null) {
// input handling
throw new NullPointerException("cannot calculate null string");
}
if (calculateCommand.startsWith("-")) {
// dealing with only one case
return additiveCalculator("0" + calculateCommand);
}
if (! calculateCommand.matches("\d+(\s*[+-]\s*\d+)*")) {
throw new IllegalArgumentException("Input '" + calculateCommand + "' is not calculable.");
}
Integer[] operands = Arrays.stream(calculateCommand.split("[+-]"))
.map(str -> str.trim())
.map(str -> Integer.parseInt(str))
.toArray(Integer[]::new);
String[] operators = calculateCommand.replaceAll("[^+-]", "").split("");
int aggregate = operands[0];
for (int i = 0; i < operators.length; i++) {
int num = operands[i+1];
String op = operators[i];
switch (op) {
case "+":
aggregate += num;
break;
case "-":
aggregate -= num;
break;
default:
// this can't happen. However, later this exception might be useful
throw new IllegalStateException("The " + i + "th operator, '" + op + "' is not an additive operator.");
}
}
return Integer.toString(aggregate);
}
我添加了评论以指出改进之处。不过,我想解释一下数字检查器正则表达式。这是 \d+(\s*[+-]\s*\d+)*
。解释如下:
\d
代表数字。相当于[0-9]
\s
代表空格。\d+
正则表达式以数字开头,也可以为零。不需要添加^
因为我们使用String.matches()
.(...)*
那么我们可以看到零个或多个:\s*[+-]\s*\d+
- 一些空格,一个运算符,一些空格,然后是一个数字