I am trying to write 2 methods that can sort a string of brackets using only 1 stack and 1 switch statement. I can't get it to work, I am wondering if it may be because of cases of ' ' in strings? should not default case pick up these or have I understood switch statements wrong? This is where I am right now.
out.println(checkParentheses("({} [()] ({}))")); // should print true
out.println(!checkParentheses("({} [() ({)})")); // should print false
Boolean checkParentheses(String brackets) {
Deque<Character> stack = new ArrayDeque<>();
for( char ch : brackets.toCharArray()) {
if (stack.peek() == matching(ch)) {
stack.pop();
} else {
stack.add(ch);
}
}
return stack.isEmpty();
}
char matching(char ch) {
// char c = (' ');
switch (ch) {
case ')':
return '('; // c = '('
case ']':
return '[';
case '}':
return '{';
default:
// return c;
throw new IllegalArgumentException("No match found");
}
}
Non-bracket characters should be ignored in the input, optionally the input may be cleaned out of them or just skipped quietly
Special checks for opening/closing brackets need to be implemented.
Basically, checkParentheses should be as simple as follows:
public static boolean checkParentheses(String str) {
if (null == str || str.isEmpty()) {
return true;
}
Deque<Character> stack = new ArrayDeque<>();
for (char c : str.toCharArray()) {
if (openingBracket(c)) {
stack.push(c);
} else if (closingBracket(c)) {
if (stack.isEmpty() || matchingBracket(c) != stack.pop()) {
return false;
}
} // else ignore non-bracket char quietly
}
return stack.isEmpty();
}
Then additional methods may look as follows using switch statement:
static boolean openingBracket(char c) {
switch (c) {
case '(': case '[': case '{': case '<':
return true;
default:
return false;
}
}
static boolean closingBracket(char c) {
switch (c) {
case ')': case ']': case '}': case '>':
return true;
default:
return false;
}
}
static char matchingBracket(char c) {
switch (c) {
case ')': return '(';
case ']': return '[';
case '}': return '{';
case '>': return '<';
default:
throw new IllegalArgumentException("Bad character found instead of closing bracket: " + c);
}
}
Then the output of the tests is as follows:
System.out.println(checkParentheses("({} [()] ({}))")); // true, balance ok
System.out.println(!checkParentheses("({} [() ({)})")); // true, NOT balanced
The problem is after scanning the file called "confused.dat" it outputs 90% of what it is supposed to and the other 10% are incorrect.
I have tried exchanging methods of scanning the file but nothing really changed.
import java.util.Scanner;
import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;
public class confused {
public static boolean isBalanced(String inp) {
if ((inp.length() % 2) == 1){ return false;}
else {
Stack<Character> s = new Stack<>();
for (char brackBrick : inp.toCharArray())
switch (brackBrick) {
case '{': s.push('}'); break;
case '(': s.push(')'); break;
case '[': s.push(']'); break;
default : if (s.isEmpty() || brackBrick != s.peek()) { return false;}
s.pop();
}
return s.isEmpty();
}
}
public static void main(String[] args) /*throws FileNotFoundException*/ {
try{
Scanner scrn = new Scanner (new File("confused.dat"));
while (scrn.hasNextLine()){
boolean answer = isBalanced(scrn.nextLine());
if (answer) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
} catch (FileNotFoundException e){e.printStackTrace();}
}
}
confused.dat file:
([])
(([()])))
([()[]()])()
(([()])
([] )
(([()])))
([()[]()])()
(
(]
)(
][
Here is expected output vs. the actual output
https://imgur.com/cciHkGL
shouldn't it be a no, because
if ((inp.length() % 2) == 1){ return false;}
if (answer) {
System.out.println("Yes");
} else {
System.out.println("No");
(([()]))) is not a even number, so therefore it false, and thus will print no.
Oh, I think I got it. You were actually pretty close. First off, drop this line
if ((inp.length() % 2) == 1){ return false;}
and then ignore empty spaces by adding the following condition in your switch statement:
case ' ': break;
So all in all the updated method now looks like this
public static boolean isBalanced(String inp) {
Stack<Character> s = new Stack<>();
for (char brackBrick : inp.toCharArray()) {
switch (brackBrick) {
case '{': s.push('}'); break;
case '(': s.push(')'); break;
case '[': s.push(']'); break;
case ' ': break;
default : if (s.isEmpty() || brackBrick != s.peek()) { return false;}
s.pop();
}
}
return s.isEmpty();
}
You should now get the following output
Yes
Yes
No
Yes
No
Yes
No
Yes
No
No
No
No
In this assignment, I need to read a .txt file and determine if the expressions are correct or "Balanced". The first problem I got correct but for the second problem I am getting more output than I want. Here is the problem for #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”.
The Problem2.txt is as follows:
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
Below is my code:
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();
}
}
A simple way to have the output formatted how you want is to just put the try-catch block around where you are calling the evaluatePostfix() method (make sure to delete the try-catch block that is inside the evaluatePostfix() method):
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");
}
}
}
This way, when an exception occurs inside the evaluatePostfix() method, the method will throw the exception and the exception will be dealt with outside of the looping, thus, avoiding duplicate error messages and other unwanted effects.
I am writing a program where I should check if the opening parenthesis matches the closing one. If it doesn't match, I should display No. Otherwise, I should display yes.
This is the function I wrote, taking the input from the input buffer. However, I just keep on receiving yes for the second test case, instead of YES NO YES but the other two cases are correct.
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String[] answer = new String[values.length];
for(int i =0; i<values.length;i++){
char[] crt = values[i].toCharArray();
for(char c : crt){
switch(c){
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
if(st.isEmpty() || (st.peek() != '{'))
{
answer[i]= "NO";
break;
}
st.pop();
case ')':
if(st.isEmpty() || (st.peek() != '('))
{
answer[i]= "NO";
break;
}
st.pop();
case ']':
if(st.isEmpty() || (st.peek() != '['))
{
answer[i]= "NO";
break;
}
st.pop();
}
}
if(st.isEmpty() && answer[i].equals("NO") ){
answer[i]="YES";
System.out.println("I set answer[" + i + "] = YES due to stack being empty");
}
else
{
answer[i]="NO";
System.out.println("I set answer[" + i + "] = NO due to stack being non-empty");
}
st.clear();
}
return answer;
}
Change stack.firstElement() to stack.peek(), you need the stack top instead of the first element. (firstElement is not a Stack method)
The great secret of StackOverflow is that it's not actually full of gurus who look at your code the way Neo looks at The Matrix. It's just people examining how your programs runs.
You can do this yourself, and the most ancient and trivial way is through so-called "print debugging".
In short, you just add print statements that prints what your code is doing, and then you follow along and compare it to what you think it should be doing. Here's your code with such print statements added:
import java.util.*;
public class Test {
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String[] answer = new String[values.length];
for(int i =0; i<values.length;i++){
char[] crt = values[i].toCharArray();
boolean an = false;
for(char c : crt){
switch(c){
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
if(st.isEmpty() || (st.firstElement() != '{'))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched }");
}
st.pop();
break;
case ')':
if(st.isEmpty() || (st.firstElement() != '('))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched )");
}
st.pop();
break;
case ']':
if(st.isEmpty() || (st.firstElement() != '['))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched ]");
}
st.pop();
break;
}
}
if(st.isEmpty()){
answer[i]="yes";
System.out.println("I set answer[" + i + "] = YES due to stack being empty");
}
else
{
answer[i]="no";
System.out.println("I set answer[" + i + "] = NO due to stack being non-empty");
}
st.clear();
}
return answer;
}
public static void main(String[] args) {
String[] result = braces(new String[] { "(foo}" });
for(String s : result) System.out.println("The final result is " + s);
}
}
And here's the output, running on the string (foo}:
I set answer[0] = NO due to mismatched }
I set answer[0] = YES due to stack being empty
The final result is yes
Welp, it looks like you're overwriting your previous answer. You should make sure the final test doesn't override the loop's conclusion.
The trivial hack would be to check if answer[i] is null, but the better way would be to create a second helper method boolean braces(String) that is free to return true or false at any time, and then simply call that function in a loop in your braces(String[])
In any case, this would have been my implementation:
import java.util.Stack;
class Test {
static char flip(char c) {
switch(c) {
case '}': return '{';
case ')': return '(';
case ']': return '[';
default: throw new IllegalArgumentException("Invalid paren " + c);
}
}
static boolean matched(String value) {
Stack<Character> st = new Stack<Character>();
for (int i=0; i<value.length(); i++) {
char c = value.charAt(i);
switch(c) {
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
case ')':
case ']':
if (st.isEmpty() || st.peek() != flip(c)) {
return false;
}
st.pop();
break;
}
}
return st.isEmpty();
}
static String[] braces(String[] values) {
String[] result = new String[values.length];
for(int i=0; i<result.length; i++) {
result[i] = matched(values[i]) ? "yes" : "no";
}
return result;
}
public static void main(String[] args) {
String[] input = new String[] { "}", "{}", "{()}", "asdf", "", "{[", "{[[([])]]}", "((foo))" };
String[] actual = braces(input);
String[] expected = new String[] { "no", "yes", "yes", "yes", "yes", "no", "yes", "yes" };
for(int i=0; i<actual.length; i++) {
if(!actual[i].equals(expected[i])) {
System.out.println("Failed: " + input[i] + " should have been " + expected[i]);
System.exit(1);
}
}
System.out.println("OK");
}
}
import java.util.*;
import java.util.stream.Collectors;
public class Test {
static final Map<Character, Character> PARENS;
static final Set<Character> CLOSING_PARENS;
static {
PARENS = new HashMap<>();
PARENS.put('{', '}');
PARENS.put('[', ']');
PARENS.put('(', ')');
CLOSING_PARENS = new HashSet<>(PARENS.values());
}
public static void main(String[] args) {
print(braces("(foo}","[]","()","{}","[{}]","([{}])","[[]]"));
print(braces("[","]","][","[{]}"));
// test case 2 ...
print(braces("{[()]}","{[(])}","{{[[(())]]}}"));
// ... prints YES NO YES ...
}
static void print(String ... values){
for(String str : values){
System.out.print(str + " ");
}
System.out.println();
}
static String [] braces(String ... values) {
return Arrays.stream(values)
.map(Test::isBalanced)
.map(b -> b ? "YES" : "NO")
.collect(Collectors.toList()).toArray(new String[values.length]);
}
static boolean isBalanced(String token){
Stack<Character> stack = new Stack<>();
for(char c : token.toCharArray()){
if (PARENS.keySet().contains(c)){
stack.push(c);
} else if(CLOSING_PARENS.contains(c)){
if(stack.isEmpty() || !PARENS.get(stack.pop()).equals(c)) {
return false;
}
}
}
return stack.isEmpty();
}
}
you just have to make the following changes
Replace firstElement() with peek() in all cases
remove the following statement from the first two cases
stack.pop();
break;
check if stack is empity at the last case
if(!stack.isEmpty())
corrected code:
public class ParenMatch{
public static void main(String[] args){
String[] str = { "{}[](){[}]","{[()]}{[(])}{{[[(())]]}}","", "}][}}(}][))][](){()}()({}([][]))[](){)[](}]}]}))}(())(([[)"};
System.out.println(Arrays.toString(braces(str)));
}
public static String[] braces(String[] values)
{
Stack<Character> stack = new Stack<Character>();
String[] isCorrect = new String[values.length];
for (int i = 0; i < values.length; i++)
{
char[] crt = values[i].toCharArray();
boolean an = false;
for (char c : crt)
{
switch(c)
{
case '{':
case '(':
case '[':
stack.push(c);
break;
case '}':
if (stack.isEmpty() || (stack.peek() != '{'))
{
isCorrect[i] = "NO";
}
//stack.pop();
//break;
case ')':
if (stack.isEmpty() || (stack.peek() != '('))
{
isCorrect[i] = "NO";
}
//stack.pop();
//break;
case ']':
if (stack.isEmpty() || (stack.peek() != '['))
{
isCorrect[i] = "NO";
}
if(!stack.isEmpty())
stack.pop();
break;
}
}
if (stack.isEmpty())
{
isCorrect[i] = "yes";
}
else
{
isCorrect[i] = "no";
}
stack.clear();
}
return isCorrect;
}
}
input:
String[] str = { "{}[](){[}]","{[()]}{[(])}{{[[(())]]}}","", "}][}}(}][))][](){()}()({}([][]))[](){)[](}]}]}))}(())(([[)"};
output:
[yes, yes, yes, no]
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String []answer = new String[values.length];
Boolean isCorrect = false;
for(int i =0; i< values.length;i++)
{
isCorrect = true;
st.clear();
char crt[] = values[i].toCharArray();
for(char c : crt)
{
switch(c)
{
case'{':
case'[':
case'(':
st.push(c);
break;
case'}':
if(st.isEmpty() || st.peek() != '{')
{
System.out.println("Hellooo");
answer[i] ="NO";
isCorrect = false;
}
if(!st.isEmpty())
{
st.pop();
}
break;
case']':
if(st.isEmpty() || st.peek() != '[')
{
System.out.println("Hell");
answer[i] ="NO";
isCorrect = false;
}
if(!st.isEmpty())
{
st.pop();
}
break;
case')':
if(st.isEmpty() || st.peek() != '(')
{
isCorrect = false;
}
if(!st.isEmpty()) {
st.pop();
}
break;
}
}
if(isCorrect && st.isEmpty())
{
answer[i] = "YES";
System.out.println("Hello");
}else answer[i] = "NO";
}
return answer;
}
This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I tried making my infix to postfix code, it works without the braces, but when I try to include the portion to account for braces, it crashes, here is the main part of the code:
for (i=0; i<characters.length; i++)
{
if (characters[i]=='*' || characters[i]=='/' || characters[i]=='+' || characters[i]=='-' || characters[i]=='(' || characters[i]==')'){
if (postfix.empty() && characters[i]!=')')
postfix.push(characters[i]);
else if (!postfix.empty()){
if (characters[i]=='(')
postfix.push(characters[i]);
if (characters[i]=='*' || characters[i]=='/')
priority2=1;
if (characters[i]=='+' || characters[i]=='-')
priority2=0;
if (characters[i]==')'){
while (postfix.peek()!='(') //loop until we see the closing bracket
System.out.print(postfix.pop()); //pop everything till we see the closing bracket
postfix.pop(); //to pop the bracket
}
if (!postfix.empty())
peeked=postfix.peek();
if (peeked=='*' || peeked=='/')
priority=1;
if (peeked=='+' || peeked=='-')
priority=0;
if (priority2>priority)
postfix.push(characters[i]);
else{
while (!postfix.empty())
System.out.print(postfix.pop());
postfix.push(characters[i]);
}
}
}
else
System.out.print(characters[i]);
}
while (!postfix.empty())
System.out.print(postfix.pop());
Any help would be appreciated. It breaks when it comes to a brace.
You can get some insight from my implementation of Infix To Postfix program, which is based on the standard algorithm for doing such conversions. Here it is:
import java.util.Scanner;
import java.util.Stack;
public class InfixPostfix
{
private Stack<Character> stack;
private StringBuilder postfixExpression;
public InfixPostfix()
{
stack = new Stack<>();
postfixExpression = new StringBuilder();
String infix = getInfixExpression();
if (isValidInfix(infix))
{
System.out.println(convertToPostfix(infix));
}
else
{
System.out.println("Invalid Expression");
}
}
private boolean isValidInfix(String infix)
{
int parenthesisCounter = 0;
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
if (ch == '(')
parenthesisCounter++;
else if (ch == ')')
parenthesisCounter--;
if (parenthesisCounter < 0)
return false;
}
if (parenthesisCounter == 0)
return true;
return false;
}
private String convertToPostfix(String infix)
{
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
switch (ch)
{
case '+':
case '-':
processOperatorOfPrecedence(ch, 1);
break;
case '*':
case '/':
processOperatorOfPrecedence(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
processParenthesis(ch);
break;
default:
postfixExpression.append(ch);
break;
}
}
while (!stack.isEmpty())
{
postfixExpression.append(stack.pop());
}
return postfixExpression.toString();
}
private void processOperatorOfPrecedence(char operator, int precedence)
{
while (!stack.isEmpty())
{
char topOperator = stack.pop();
if (topOperator == '(')
{
stack.push(topOperator);
break;
}
else
{
int operatorPrecedence;
if (topOperator == '+' || topOperator == '-')
operatorPrecedence = 1;
else
operatorPrecedence = 2;
if (operatorPrecedence < precedence)
{
stack.push(topOperator);
break;
}
else
postfixExpression.append(topOperator);
}
}
stack.push(operator);
}
private void processParenthesis(char ch)
{
while (!stack.isEmpty())
{
char character = stack.pop();
if (character == '(')
break;
else
postfixExpression.append(character);
}
}
private String getInfixExpression()
{
Scanner scanner = new Scanner(System.in);
System.out.println("Enter an infix math expression: ");
String input = scanner.nextLine();
scanner.close();
return input;
}
public static void main(String[] args)
{
new InfixPostfix();
}
}