我正在尝试修复此代码,因为它由于java.lang.NumberFormatException
而未运行。这让我感到困惑,因为我之前从未遇到过这个错误。
代码必须解决诸如3 + 4 * 5
之类的表达式,同时遵循PEMDAS规则,例如在添加之前进行乘法等。我还希望它使用键盘输入,我试图自己做的事情更糟糕的是,所以我决定将其删除。
import java.util.*;
import static java.lang.Integer.*;
import static java.lang.System.*;
import java.lang.*;
class ExpressionSolver_Rumenov
{
private ArrayList<String> list;
private String expression;
private String trimmedExp;
private String evaluated;
private int eval;
public ExpressionSolver_Rumenov(String s)
{
list=new ArrayList<String>();
expression=s;
trimmedExp=s.trim();
for (int x=0; x<trimmedExp.length(); x++)
{
list.add(""+trimmedExp.charAt(x));
}
}
public void setExpression(String s)
{
expression=s;
trimmedExp=s.trim();
list.clear();
for (int x=0; x<trimmedExp.length(); x++)
{
list.add(""+trimmedExp.charAt(x));
}
}
public void solveExpression()
{
eval=0;
for (int x=0; x<list.size(); x++)
{
if (list.get(x).equals("*")||list.get(x).equals("/"))
{
if (list.get(x).equals("*"))
{
list.set(x-1, String.valueOf(Integer.parseInt(list.get(x-1))*Integer.parseInt(list.get(x+1))));
list.remove(x+1);
list.remove(x);
}
else if(list.get(x).equals("/"))
{
list.set(x-1, String.valueOf(Integer.parseInt(list.get(x-1))/Integer.parseInt(list.get(x+1))));
list.remove(x+1);
list.remove(x);
}
}
}
for (int x=0; x<list.size(); x++)
{
if (list.get(x).equals("-"))
{
list.set(x-1, String.valueOf(Integer.parseInt(list.get(x-1))-Integer.parseInt(list.get(x+1))));
list.remove(x);
list.remove(x+1);
}
else if (list.get(x).equals("+"))
{
list.remove(x);
}
}
for (int x=0; x<list.size(); x++)
{
if (list.get(x).equals(" "))
{
list.remove(x);
}
list.set(x, list.get(x).trim());
}
for (int x=0; x<list.size(); x++)
{
eval+=Integer.parseInt(list.get(x));
}
evaluated=String.valueOf(eval);
}
public String toString( )
{
return evaluated;
}
}
public class Lab04
{
public static void main( String args[] )
{
ExpressionSolver_Rumenov test = new ExpressionSolver_Rumenov("3 + 5");
test.solveExpression();
out.println(test.toString());
test.setExpression("3 * 5");
test.solveExpression();
out.println(test);
test.setExpression("3 - 5");
test.solveExpression();
out.println(test);
test.setExpression("3 / 5");
test.solveExpression();
out.println(test);
test.setExpression("5 * 5 + 2 / 2 - 8 + 5 * 5 - 2");
test.solveExpression();
out.println(test);
}
}
答案 0 :(得分:0)
根据Oracle的JavaDocs,NumberFormatException:
抛出以指示应用程序已尝试转换a 字符串到其中一个数字类型,但字符串没有 适当的格式。
您的问题是您正在尝试将不是数字的某些内容转换为数字。问题可能来自解析,比如阅读空间并尝试将它们转换为数字。
编辑: 为了解析我建议你看看&#34; Shunting Yard&#34;维基百科中的算法: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
答案 1 :(得分:0)
您正尝试将" "
字符解析为第eval+=Integer.parseInt(list.get(x));
行的整数。发生这种情况是因为您没有从列表中正确删除空格。
在这里,您正在x<list.size()
条件上运行循环,当循环运行时,您还要从中删除元素。在将循环终止与list.size()进行比较时,无法动态更改列表大小。这不是你在列表中循环的方式。
// not a correct way
for (int x=0; x<list.size(); x++)
{
if (list.get(x).equals(" "))
{
list.remove(x);
}
list.set(x, list.get(x).trim());
}
相反,您应该使用list Iterator。像这样,
// correct way
Iterator iter = list.iterator();
while (iter.hasNext()) {
if(iter.next().equals(" "))
iter.remove();
}
您应该在迭代列表的同时更新代码并同时从中删除元素。
答案 2 :(得分:0)
最重要的是,您尝试将非整数字符提供给Integer.parseInt()
。如果您修复了Lab04
驱动程序类中的表达式,那么您将看到一切正常。
例如,而不是:
ExpressionSolver_Rumenov test = new ExpressionSolver_Rumenov("3 + 5");
尝试此操作,删除空格字符:
ExpressionSolver_Rumenov test = new ExpressionSolver_Rumenov("3+5");
然而,您可能想要一个更容错的程序,因此您需要做一些工作,特别是如果您希望用户能够输入自己的数据。
我认为你可能会误解String.trim()
的作用。 trim()
方法从String中删除前导空格和尾随空格,因此如果在String的开头有一个制表符,最后一个换行符,trim()
将删除那些。
然而,trim()
不会做的是摆脱散布在整个字符串中的空白。为此,你需要自己修剪空白,或者只是忽略空格字符。
要从字符串中删除空格字符,请在setExpression
方法中替换:
expression=s;
与
expression = s.replaceAll("\\s+","");
当然,你仍然可以忽略空白。而不是:
char c = trimmedExp.charAt(x);
list.add("" + c);
尝试:
char c = trimmedExp.charAt(x);
if(c != " ")
{
list.add("" + c);
}
请注意,在这种情况下您需要Character
进行比较,因此应使用==
,而不是.equals()
。
答案 3 :(得分:0)
(.trim())的范围是删除字符串表达式之前和之后的空格,如链接打击
https://www.w3schools.com/jsref/jsref_trim_string.asp
ex:String name =“我的名字是穆罕默德”; 我们在表达式之前有两个空格,后面有一个空格 所以如果我们应用.trim()就像打击
一样String newName = name.trim(); 我们将收到“我的名字是Muhamad”而不是“mynameisMuhamad”作为newName的值