В этом задании мне нужно прочитать файл .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();
}
}
Это выражения, которые дал мне мой учитель, и я не могу их изменить. Мой код по-прежнему дает мне правильный ответ, который я ищу. Я полагаю, что проблема с получением нескольких неправильно отформатированных выражений заключается в выражении 2.
Что ж, второе выражение определенно плохо отформатировано, потому что * появляется только с одним доступным операндом в стеке. У меня нет проблем с вашим выводом для второго выражения.
С моей стороны, я получаю 3 плохих формата, а не только 1. Вы знаете, почему это может быть?
Вы получаете несколько «неправильно сформированных» сообщений и неожиданный результат, потому что продолжаете пытаться оценить выражение после того, как вы определили его неправильный формат. Вместо того, чтобы печатать сообщение в предложении catch, вам нужно выполнить цикл break;' out of the for` и тогда отобразить ошибку.
Спасибо за вашу помощь, в настоящее время я работаю над тем, что вы только что прокомментировали, и когда я выхожу из цикла for, сообщение об ошибке недоступно. Могу ли я разместить свой перерыв прямо под заявлением об улове? или мне нужно переместить сообщение об ошибке?




Простой способ отформатировать вывод так, как вы хотите, - просто поместить блок 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() возникает исключение, метод генерирует исключение, и исключение обрабатывается вне цикла, что позволяет избежать дублирования сообщений об ошибках и других нежелательных эффектов.
Я думаю, что первое выражение
3 2 + 5 6 8 2 / + + * 1 +не является допустимым постфиксом. После первого добавления он превратился бы в5 5 6 8 2 / + + * 1 +, что не имеет смысла.