Оценка стека Java из файла TXT

В этом задании мне нужно прочитать файл .txt и определить, правильны ли выражения или «сбалансированы». Первую проблему я исправил, но по второй проблеме я получаю больше результатов, чем хочу. Проблема №2:

Write a stack-based algorithm that evaluates a post-fixed expression. Your program needs to read its input from a file called “problem2.txt”. This file contains one expression per line. For each expression output its value to the standard output. If an expression is ill-formed print “Ill-formed”.

Problem2.txt выглядит следующим образом:

3  2  +  5  6  8  2  /  +  +  *  1  + 
8 * 2  3 + + -  9 1 +
1  4  +  9  4  -  *  2  *
// For my output I need to get:
76
Ill-formed
50

// With my code I am getting:
76
Ill-formatted
Ill-formatted
Ill-formatted
10
50
// and I’m not sure why I’m getting extra ill-formatted and a 10 in there

Ниже мой код:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;
import java.util.EmptyStackException;

public class Eval {

    public static void main(String args[]) throws IOException {
    //driver
        try (BufferedReader filereader = new BufferedReader(new FileReader("Problem1.txt"))) {
            while (true) {
                String line = filereader.readLine();
                if (line == null) {
                   break;
                }

                System.out.println(balancedP(line));
            }
        }
        System.out.println("\n");
        try (BufferedReader filereader2 = new BufferedReader(new FileReader("Problem2.txt"))) {
            while (true) {
                String line = filereader2.readLine();
                if (line == null) {
                   break;
                }

                System.out.println(evaluatePostfix(line));
            }
        }
    }


    public static boolean balancedP (String s) {
        Stack<Character> stackEval  = new Stack<Character>();

        for(int i = 0; i < s.length(); i++) {

            char token = s.charAt(i);

            if (token == '[' || token == '(' || token == '{' ) {     
                stackEval.push(token);
            } else if (token == ']') {
                if (stackEval.isEmpty() || stackEval.pop() != '[') {
                    return false;
                }
            } else if (token == ')') {
                if (stackEval.isEmpty() || stackEval.pop() != '(') {
                    return false;
                }           
            } else if (token == '}') {
                if (stackEval.isEmpty() || stackEval.pop() != '{') {
                    return false;
                }
            }
        }
        return stackEval.isEmpty();
       }



    //problem 2 algo to evaluate a post-fixed expression
    static int evaluatePostfix(String exp) throws EmptyStackException
    { 
        Stack<Integer> stackEval2 = new Stack<>(); 

        for(int i = 0; i < exp.length(); i++) 
        { 
            char c = exp.charAt(i); 

            if (c == ' ') 
            continue; 

            else if (Character.isDigit(c)) { 
                int n = 0; 

                while(Character.isDigit(c)) { 
                   n = n*10 + (int)(c-'0'); 
                    i++; 
                    c = exp.charAt(i); 
                } 
                i--; 

                stackEval2.push(n); 
            } 

            else { 

                try {
                //if operand pops two values to do the calculation through the switch statement
                int val1 = stackEval2.pop(); 

                int val2 = stackEval2.pop(); 
                //operands in a switch to test and do the operator's function each value grabbed and tested
                switch(c) { 
                    case '+': 
                    stackEval2.push(val2 + val1); 
                    break; 

                    case '-': 
                    stackEval2.push(val2 - val1); 
                    break; 

                    case '/': 
                    stackEval2.push(val2 / val1); 
                    break; 

                    case '*': 
                    stackEval2.push(val2 * val1); 
                    break; 
                } 
                } catch (EmptyStackException e) {
                    System.out.println("Ill-formatted");
                }
            } 
        } 
        return stackEval2.pop();  
    } 
}

Я думаю, что первое выражение 3 2 + 5 6 8 2 / + + * 1 + не является допустимым постфиксом. После первого добавления он превратился бы в 5 5 6 8 2 / + + * 1 +, что не имеет смысла.

Tim Biegeleisen 17.10.2018 04:38

Это выражения, которые дал мне мой учитель, и я не могу их изменить. Мой код по-прежнему дает мне правильный ответ, который я ищу. Я полагаю, что проблема с получением нескольких неправильно отформатированных выражений заключается в выражении 2.

Bill Dalow 17.10.2018 04:45

Что ж, второе выражение определенно плохо отформатировано, потому что * появляется только с одним доступным операндом в стеке. У меня нет проблем с вашим выводом для второго выражения.

Tim Biegeleisen 17.10.2018 04:47

С моей стороны, я получаю 3 плохих формата, а не только 1. Вы знаете, почему это может быть?

Bill Dalow 17.10.2018 04:48

Вы получаете несколько «неправильно сформированных» сообщений и неожиданный результат, потому что продолжаете пытаться оценить выражение после того, как вы определили его неправильный формат. Вместо того, чтобы печатать сообщение в предложении catch, вам нужно выполнить цикл break;' out of the for` и тогда отобразить ошибку.

Kevin Anderson 17.10.2018 04:48

Спасибо за вашу помощь, в настоящее время я работаю над тем, что вы только что прокомментировали, и когда я выхожу из цикла for, сообщение об ошибке недоступно. Могу ли я разместить свой перерыв прямо под заявлением об улове? или мне нужно переместить сообщение об ошибке?

Bill Dalow 17.10.2018 05:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
6
290
1

Ответы 1

Простой способ отформатировать вывод так, как вы хотите, - просто поместить блок try-catch в место, где вы вызываете метод evaluatePostfix() (обязательно удалите блок try-catch, который находится внутри метода evaluatePostfix()):

System.out.println("\n");
try (BufferedReader filereader2 = new BufferedReader(new FileReader("Problem2.txt"))) {
    while (true) {
        String line = filereader2.readLine();
        if (line == null) {
            break;
        }

        try {
            System.out.println(evaluatePostfix(line));
        } catch (EmptyStackException e) {
            System.out.println("Ill-formatted");
        }
    }
}

Таким образом, когда внутри метода evaluatePostfix() возникает исключение, метод генерирует исключение, и исключение обрабатывается вне цикла, что позволяет избежать дублирования сообщений об ошибках и других нежелательных эффектов.

Другие вопросы по теме