英文:
How to process input one number at a time through a while loop
问题
我的主要方法要求用户输入一个表达式,输入将类似于“5 4 +”或“6 4 + 8 /”,其中操作数和运算符由空格分隔。我有一个处理此输入的方法,并给出了它等于什么的答案。它通过循环遍历所有通过while循环输入的数字,该循环在scnr.hasNext() == true
或者当errorMessage
不为null时结束。目前,scnr.hasNext()
变得比预期早地变为false,导致循环只读取第一个数字,然后结束。它之所以变为false,是因为我尝试将scnr.nextInt()
存储到一个变量中。我需要它只取第一个数字,然后留下剩下的部分,我认为这会保持scnr.hasNext()
为true。以下是整个方法的代码:
public static Number evaluateExpression(String expr) {
int var = 0;
String input = "";
String tooFewOperands = "Too few operands";
String unKnownOperator = "Unknown operator:";
String tooManyOperands = "Too many operands.";
Stack<Integer> stack = new Stack<>();
String errMsg = null;
Scanner scnr = new Scanner(expr);
while (scnr.hasNext() && errMsg == null) {
if (scnr.hasNextInt()) {
var = scnr.nextInt(); //存在问题的代码行
System.out.println("Operand read: " + var);
stack.push(var);
} else {
input = scnr.next();
if (checkValidOperator(input) == input.toCharArray()[0]) {
System.out.println("Operator read: " + input);
// stack.push(var);
if (stack.size() >= 2) {
execute(stack, input.toCharArray()[0]);
} else {
errMsg = tooFewOperands;
}
} else {
errMsg = unKnownOperator + " " + input + " ";
}
}
System.out.println("------ Stack state -----");
System.out.println(stack.toString());
System.out.println(scnr.hasNext());
}
if (errMsg != null) {
System.out.println("Failed evaluation of |" + expr + "|\n" + errMsg);
return null;
}
if (stack.size() > 1) {
System.out.println("Failed evaluation of |" + expr + "|\n" + tooManyOperands + stack.toString());
return null;
} else {
return stack.peek();
}
}
请注意,Scanner scnr
是使用String expr
初始化的,我认为我的老师提到过这使我可以从scnr
中读取单个标记。她说:“使用expr作为其构造函数的参数初始化扫描仪,这将允许您从表达式中读取标记。”我以前从未使用过除了System.in
之外的东西来初始化Scanner。她还明确指出,为了创建这个方法,我应该“编写一个循环,只要扫描仪有输入(hasNext),并且错误消息为null,循环就会运行”。所以这就是while循环的条件。
英文:
My main method asks the user for an expression, an input that will be something like "5 4 +" or "6 4 + 8 /" with operands and operators separated by a space. I have a method that processes this input and gives the answer to what it equals. It loops through all the numbers inputted through a while loop that ends once scnr.hasNext() == true
, or when the errorMessage isn't null. Currently, scnr.hasNext()
is becoming false sooner than its supposed to, causing the loop to only read the first number, and then end. It is becoming false because I try to store scnr.nextInt()
into a variable. I need for it to take just the first number, and leave the rest, which I think will keep scnr.hasNext()
true. Here is my entire method
public static Number evaluateExpression(String expr) {
int var = 0;
String input = "";
String tooFewOperands = "Too few operands";
String unKnownOperator = "Unknown operator:";
String tooManyOperands = "Too many operands.";
Stack<Integer> stack = new Stack<>();
String errMsg = null;
Scanner scnr = new Scanner(expr);
while (scnr.hasNext() && errMsg == null) {
if (scnr.hasNextInt()) {
var = scnr.nextInt(); //Problematic line
System.out.println("Operand read: " + var);
stack.push(var);
} else {
input = scnr.next();
if (checkValidOperator(input) == input.toCharArray()[0]) {
System.out.println("Operator read: " + input);
// stack.push(var);
if (stack.size() >= 2) {
execute(stack, input.toCharArray()[0]);
} else {
errMsg = tooFewOperands;
}
} else {
errMsg = unKnownOperator + " " + input + " ";
}
}
System.out.println("------ Stack state -----");
System.out.println(stack.toString());
System.out.println(scnr.hasNext());
}
if (errMsg != null) {
System.out.println("Failed evaluation of |" + expr + "|\n" + errMsg);
return null;
}
if (stack.size() > 1) {
System.out.println("Failed evaluation of |" + expr + "|\n" + tooManyOperands + stack.toString());
return null;
} else {
return stack.peek();
}
}
Notice that Scanner scnr
is initialized with String expr
, I think my teacher hinted at that allowing me to read individual tokens from the scnr
. She said "Initialize a scanner using expr as a parameter to its constructor, which will allow you to read tokens from the expression." I've never initialized a Scanner with something other than System.in
. She also specified that to make this method I should "Write a loop that will run as long as the scanner has input (hasNext) and error message is null." So that is what the while condition has to be.
答案1
得分: 0
一般来说,当你为字符串类型和数值类型分别创建Scanner对象时,会出现(或者至少对我来说曾经出现过)问题。
我所做的是使用var = Integer.parseInt(scnr.nextLine());
代替。
希望能对你有帮助。
英文:
In general When you make a Scanner object for both String types and Numerical types it occurs (or at least it has happened to me).
What I done was to use var = Integer.parseInt(scnr.nextLine());
instead.
Hope it help you.
答案2
得分: 0
我对你的Scanner
代码结构没有看出任何问题。
唯一的观察是这一行看起来有点奇怪:
if (checkValidOperator(input) == input.toCharArray()[0])
checkValidOperator
的实现是什么?
这个简化版本似乎没有任何问题。将其与你的版本进行比较,看看是否可以确定可能导致问题的元素。
public static void main(String[] args)
{
String expr = "6 4 + 8 /";
Scanner scnr = new Scanner(expr);
String errorMsg = null;
while (scnr.hasNext() && errorMsg == null)
{
if (scnr.hasNextInt())
{
int var = scnr.nextInt();
System.out.println("Operand: " + var);
}
else
{
String operator = scnr.next();
if (isOperator(operator))
{
System.out.println("Operator: " + operator);
}
else
{
errorMsg = "Unknown Operator: " + operator;
}
}
}
}
static boolean isOperator(String op)
{
return op.length() == 1 && "+-*/".indexOf(op) >= 0;
}
英文:
I don't see anything wrong with the structure of your Scanner
code.
The only observation would be that this line looks odd:
if (checkValidOperator(input) == input.toCharArray()[0])
What's the implementation of checkValidOperator
?
This bare bones version appears to work without any issues. Compare this to your version to see if you can identify which elements might be causing the problem.
public static void main(String[] args)
{
String expr = "6 4 + 8 /";
Scanner scnr = new Scanner(expr);
String errorMsg = null;
while (scnr.hasNext() && errorMsg == null)
{
if (scnr.hasNextInt())
{
int var = scnr.nextInt();
System.out.println("Operand: " + var);
}
else
{
String operator = scnr.next();
if (isOperator(operator))
{
System.out.println("Operator: " + operator);
}
else
{
errorMsg = "Unknown Operator: " + operator;
}
}
}
}
static boolean isOperator(String op)
{
return op.length() == 1 && "+-*/".indexOf(op) >= 0;
}
专注分享java语言的经验与见解,让所有开发者获益!
评论