Java 使用正则表达式运行计算器程序时出现NumberFormatException
我正在尝试编写一个简单的计算器Java 使用正则表达式运行计算器程序时出现NumberFormatException,java,regex,numberformatexception,Java,Regex,Numberformatexception,我正在尝试编写一个简单的计算器 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.
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");
}
试试这个
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;
}
公共静态字符串计算器(){
字符串a=“-60-1+40”;
如果(a.匹配(“-?[1-9][0-9]?([\\+-][1-9][0-9]?)+”){
系统输出打印项次(a);
字符串运算符[]=a.split(“[0-9]+”);
字符串操作数[]=a.split(“[+-]”);
int agregate=操作数[0].isEmpty()?0:Integer.parseInt(操作数[0]);//更改的代码
对于@Ben的注释之后的(int i=1;i),一种解决方法是检查第一个字符是否为“-
”,在这种情况下,在处理字符串之前,先将0
预先写入字符串(-n可以通过从0中提取数字n获得):
-1+2-3
,应该变成0-1+2-3
if(a.startsWith("-")){
a = "0" + a;
}
简短回答
简单的回答是,您可以像这样过滤掉空字符串。流是相对较新的API,编写它们可能很困难。但是,我相信它们很容易阅读。因此,这里是:
String operands[] = Arrays.stream(calculateCommand.split("[+-]"))
.filter(str -> str != null && 0 < str.trim().length()) // skipping the empty elements
.toArray(String[]::new);
这里有一个拖拉式的答案。只要函数始终返回相同的结果,您就可以继续使用此快捷方式:
返工
上面的修复程序都不能满足您的需要。我放弃了修复该方法。相反,我编写了另一个函数:
// 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);
}
//让读者知道这个计算器只能处理+和-运算
公共静态字符串加法计算器(字符串计算器命令){
if(calculateCommand==null){
//输入处理
抛出新的NullPointerException(“无法计算空字符串”);
}
if(calculateCommand.startsWith(“-”){
//只处理一个案件
返回加法计算器(“0”+计算命令);
}
如果(!calculateCommand.matches(\\d+(\\s*[+-]\\s*\\d+*)){
抛出新的IllegalArgumentException(“输入'”+calculateCommand+“'不可计算”);
}
整数[]操作数=数组.stream(calculateCommand.split(“[+-]”)
.map(str->str.trim())
.map(str->Integer.parseInt(str))
.toArray(整数[]::新建);
String[]operators=calculateCommand.replaceAll(“[^+-]”),split(“”);
int聚合=操作数[0];
for(int i=0;i
我添加了一些注释来指出改进之处。不过我想解释一下数字检查器regex。它是\\d+(\\s*[+-]\\s*\\d+*
。下面是解释:
\\d
代表数字。等同于[0-9]
\\s
表示空白
\\d+
正则表达式以一个数字开头,该数字也可以是零。无需添加^
,因为我们使用String.matches()
(…)*
然后我们可以看到零个或多个:
\\s*[+-]\\s*\\d+
-一些空格,一个运算符,更多的空格,然后是一个数字
空字符串不是数值,无法解析为一。这正是错误消息所说的,但我不明白为什么当字符串为-60-1+40时它会失败,但当它为60-1+40时是好的,你在-
上拆分,这会留下一个空的第一个元素。这与你将要编写一样de>60+-1
这将导致“60”,“1”
。继续检查您的测试用例。让我们知道是否需要覆盖其中的任何一个。您可能需要解释您更改了什么,以及为什么在这段代码中您试图在整数中强制转换空字符串,而这将不起作用,操作数[0]
如果您输入(-),您将得到空字符串在字符串的开头。这可以修复异常,但计算不正确,就像结果总是字符串的第一个数字,即:-6+1=-6或6+1=6,但@Juan给出的解决方案有效!!
public static String cal() {
String a = "-60-1+40"; // a reminder for the developer
return "-21"; // a correct answer for the input above
}
// 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);
}