Как обработать ввод одного числа за раз через цикл while - PullRequest
0 голосов
/ 05 апреля 2020

Мой основной метод запрашивает у пользователя выражение, которое будет иметь вид «5 4 +» или «6 4 + 8 /» с операндами и операторами, разделенными пробелом. У меня есть метод, который обрабатывает этот вход и дает ответ на то, что он равен. Он перебирает все числа, введенные через некоторое время l oop, которое заканчивается один раз scnr.hasNext() == true, или когда errorMessage не равно нулю. В настоящее время scnr.hasNext() становится ложным раньше, чем предполагалось, в результате чего l oop читает только первое число, а затем завершается. Это становится ложным, потому что я пытаюсь сохранить scnr.nextInt() в переменной. Мне нужно, чтобы он взял только первое число и оставил остальные, которые, я думаю, сохранят scnr.hasNext() истинным. Вот весь мой метод

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();
        }
    }

Обратите внимание, что Scanner scnr инициализируется с String expr, я думаю, что мой учитель намекнул на это, что позволяет мне читать отдельные токены из scnr. Она сказала: «Инициализируйте сканер, используя expr в качестве параметра для его конструктора, который позволит вам читать токены из выражения». Я никогда не инициализировал сканер с чем-то кроме System.in. Она также указала, что для создания этого метода я должен «написать al oop, который будет работать, пока сканер имеет входные данные (hasNext) и сообщение об ошибке равно нулю». Так вот, какое должно быть условие while.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Я не вижу ничего плохого в структуре вашего 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;
}
0 голосов
/ 05 апреля 2020

В общем, когда вы создаете объект Scanner как для строковых, так и для числовых типов, это происходит (или, по крайней мере, со мной).

Я использовал вместо этого var = Integer.parseInt(scnr.nextLine());.

Надеюсь, это поможет вам.

...