Оценка выражения in-fix - исключение NoSuchElementFound

1

Мое назначение - оценивать выражения, считываемые из файла, такие как (4-7)/2 + 6 <3 * (1-9).

<и> означают минимум и максимум, соответственно, и имеют более высокий приоритет, чем/и *.

Тем не менее, я получаю исключение NoSuchElementFound при попытке оценить выражение, указывая на стек, который я возвращаю в конце метода оценки. Я предполагаю, что это означает, что стек пуст. У меня проблемы с тем, где проблема. Вот мой код оценки. Для чего это важно, я реализовал свои собственные классы стека (обе строки) и не использую дженерики.

/**
 * Evaluates the expression and updates textArea appropriately
 */
private String evaluateLine()
{
    char token;
    String[] tokens = new String[expression[0].length()];
    for(int i = 0; i < expression[0].length(); i++)
    {
         token = expression[0].charAt(i);
         tokens[i] = String.valueOf(token);
    }

    OperatorStack operators = new OperatorStack();
    IntegerStack integers = new IntegerStack();

    for(int i = 0; i < tokens.length; i++)
    {
        if(isInteger(tokens[i]))
        {
            integers.push(tokens[i]);
        }
        else if(tokens[i] == "(")
        {
            operators.push(tokens[i]);
        }
        else if(tokens[i] == ")")
        {
            while(operators.top() != "(")
            {
                integers.push(applyOp(operators.pop(), integers.pop(), integers.pop()));
                operators.pop();
            }
        }
        else if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/" 
                || tokens[i] == "<" || tokens[i] == ">")
        {
            while(!operators.isEmpty() && hasPrecedence(tokens[i], operators.top(), operators.top()))
            {
                integers.push(applyOp(operators.pop(), integers.pop(), integers.pop()));
            }
            operators.push(tokens[i]);
        }
    }

    while(!operators.isEmpty())
    {
        integers.push(applyOp(operators.pop(), integers.pop(), integers.pop()));
    }

    return integers.pop();
}

public static boolean hasPrecedence(String op1, String op2, String op3)
{

    if(op2 == "(" || op2 == ")")
    {
        return false;
    }

    if((op1 == "<" || op1 == ">") && (op2 == "*" || op2 == "/") && (op3 == "+" || op3 == "-"))
    {
        return false;
    }
    else
    {
        return true;
    }
}

public static String applyOp(String op, String b, String a)
{
    switch (op)
    {
    case "+":
        return Integer.toString(Integer.parseInt(a) + Integer.parseInt(b));
    case "-":
        return Integer.toString(Integer.parseInt(a) - Integer.parseInt(b));
    case "*":
        return Integer.toString(Integer.parseInt(a) * Integer.parseInt(b));
    case "/":
        if(Integer.parseInt(b) == 0)
        {
            throw new
            UnsupportedOperationException("Cannot divide by 0");
        }
        return Integer.toString(Integer.parseInt(a) / Integer.parseInt(b));
    case "<":
        if(Integer.parseInt(a) < Integer.parseInt(b))
        {
            return b;
        }
        else if(Integer.parseInt(b) < Integer.parseInt(a))
        {
            return a;
        }
    case ">":
        if(Integer.parseInt(a) > Integer.parseInt(b))
        {
            return a;
        }
        else if(Integer.parseInt(b) > Integer.parseInt(a))
        {
            return b;
        }
    }

    return Integer.toString(0);

}

public boolean isInteger(String str)
{
    return str.matches("0123456789");
}
Теги:
parsing
expression
stack

1 ответ

0
Лучший ответ

Трудно найти точную проблему, потому что вы не включаете достаточно кода, чтобы получить свой пример для компиляции, но одна вещь, которую я замечаю, заключается в том, что ваш метод isInteger не работает. Когда я запускал вход в свой метод, он создавал пустой стек для целых чисел. Используйте это вместо этого:

public boolean isInteger(String str) {
    try {
        Integer.parseInt(str);
        return true;
    } catch (NumberFormatException ex) {
        return false;
    }
}

В качестве альтернативы, я думаю, вы пытались использовать Regex для определения, содержит ли строка целое число. Для этого вам нужно будет сделать это:

public boolean isInteger(String str) {
    return str.matches("[0-9]+");
}

С любой из этих реализаций isInteger я смог заставить ваш код работать, когда я заменяю ваш стек коллекциями Stack<String>. Надеюсь, это поможет.

  • 0
    Это помогло мне решить проблему, большое спасибо! Код не оценивается должным образом, но, по крайней мере, он работает без сбоев. Еще раз спасибо.
  • 0
    Рад, что смог помочь. Хотите пометить мой ответ как правильный?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню