Java Stack error after getting last element via pop method - java

I have the following code for the solution of Hackerrank.
public static void main(String[] args) {
System.out.println(isBalanced("{(([])[])[]}"));
}
public static String isBalanced(String s) {
Stack<Character> stack = new Stack<>();
stack.push(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
Character c = s.charAt(i);
Character cStack = stack.peek();
if (cStack == '{' && c == '}'
|| cStack == '[' && c == ']'
|| cStack == '(' && c == ')') {
stack.pop();
} else {
stack.push(c);
}
}
if (stack.isEmpty())
return "YES";
return "NO";
}
Although the code seems to working without any problem, it throws the following error on the Hackerrank page. I already test the input in my local IDE as it is {(([])[])[]}, but I am not sure if I need to get the last element (it maybe due to getting it via Character cStack = stack.peek(); and then stack.pop();.
So, could you please have a look at and test this code on Hackerrank page and let me know what is wrong?
Update:
public static String isBalanced(String s) {
Stack<Character> stack = new Stack<>();
stack.push(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
Character c = s.charAt(i);
if (c == '{' || c == '[' || c == '(') {
stack.push(c);
} else if (stack != null) {
Character cStack = stack.peek();
if (cStack == '{' && c == '}'
|| cStack == '[' && c == ']'
|| cStack == '(' && c == ')') {
stack.pop();
}
}
}
if (stack.isEmpty())
return "YES";
return "NO";
}

Before calling stack.peek(), you need to check if the stack is empty or not. Calling pop() or peek() on an empty stack will raise an error.
If the current character is an opening bracket, you don't even need to check the stack top. If it is a closing bracket, then check if the stack is empty or not first. If it is, return false. Otherwise compare the top character and make a decision.

Related

Empty Stack Exception

class Solution{
static boolean ispar(String x){
char [] arr = x.toCharArray();
int length = arr.length;
Stack<Character> stack = new Stack<>();
boolean isBalanced = true;
if(arr[0] == '}' || arr[0] == ')' || arr[0] == ']'){
isBalanced = false;
}
else{
for(int i=0; i<length; i++){
char bracket = arr[i];
if(bracket == '{' || bracket =='(' || bracket == '['){
stack.push(bracket);
}
else if(!stack.empty() &&
((char) stack.peek() == '(' && (bracket == ')'))
|| ((char) stack.peek() == '{' && bracket == '}')
|| ((char) stack.peek() == '[' && bracket == ']')
){
stack.pop();
}
else{
isBalanced = false;
}
}
if(stack.empty()){
isBalanced = true;
}
else{
isBalanced = false;
}
}
return isbalanced;
}
}
I am learning Stack data structure. And this is the first problem I am trying to solve but it is giving me this exception :
Exception in thread "main" java.util.EmptyStackException
at java.base/java.util.Stack.peek(Stack.java:102)
at Solution.ispar(File.java:57)
at Driverclass.main(File.java:23)
Here's an attempt to correct your code without changing your core attempt:
import java.util.Stack;
class Solution {
public boolean isBalancedBrackets(String str) {
char[] arr = str.toCharArray();
Stack<Character> stack = new Stack<>();
if (arr[0] == '}' || arr[0] == ')' || arr[0] == ']') {
return false;
} else {
for (char bracket : arr) {
if (bracket == '{' || bracket == '(' || bracket == '[') {
stack.push(bracket);
} else if (!stack.empty() &&
(bracket == ')' && stack.peek() == '(' ||
bracket == '}' && stack.peek() == '{' ||
bracket == ']' && stack.peek() == '[')) {
stack.pop();
} else {
return false;
}
}
}
return stack.empty();
}
}
Changes:
Removed the redundant isBalanced variable, you can just return immediately when you detect a mismatch.
For your else-if statement you need to group all the or conditions together, with one set of parentheses. This is the reason you are getting the EmptyStackException. Since you only want to check any of the three conditions if the stack is not empty.
Renamed method.
Also, consider using a Deque over a Stack in the future.
If you want to ommit letters in #Sash Sinha Solution you could add a new field:
private static Set<Character> bracketSet = Set.of('(', ')', '{', '}', '[', ']');
and the method:
public static boolean ommitLetters(Character chr) {
return bracketSet.contains(chr);
}
to implement it inside the loop:
...
for (char bracket : arr)
if (ommitLetters(bracket)) {
if (bracket == '{' || bracket == '(' || bracket == '[') {
stack.push(bracket);
} else if (!stack.empty() && (bracket == ')' && stack.peek() == '('
|| bracket == '}' && stack.peek() == '{' || bracket == ']' && stack.peek() == '[')) {
stack.pop();
} else {
return false;
}
} else
continue;
...
# Sash Sinha - yes, using HashMap removes the requirement for the multi-or statements completely, ex:
public static <K, V> K getKeyFromMapByValue(Map<K, V> map, V value) {
for (Entry<K, V> entry : map.entrySet())
if (entry.getValue().equals(value))
return entry.getKey();
return null;
}
private static Set<Character> validParenthesisSet = Set.of('(', ')', '{', '}', '[', ']');
public static boolean areParenthesisPaired(String expression) {
Stack<Character> stack = new Stack<>();
Map<Character, Character> parenthesisPairs = new HashMap<>() {
private static final long serialVersionUID = 6725243592654448763L;
{
put('(', ')');
put('{', '}');
put('[', ']');
}
};
for (Character actualParenthesis : expression.toCharArray()) {
if (validParenthesisSet.contains(actualParenthesis))
if (parenthesisPairs.containsValue(actualParenthesis)) { // must catch only closed
Character oppositeParenthesis = getKeyFromMapByValue(parenthesisPairs, actualParenthesis);
if (stack.size() == 0 || stack.peek() != oppositeParenthesis)
return false;
stack.pop();
} else
stack.push(actualParenthesis);
}
if (stack.size() > 0)
return false;
return true;
}

Parentheses matching algorithm java

This is my implementation of the parenthesis matching algorithm. However can someone tell me what is wrong. I get true all the time for example for input: {}(
public static boolean checkString(char [] stringToCheck){
Deque<Character> stack = new ArrayDeque<Character>();
for(int i= 0; i<stack.size();i++){
char current = stringToCheck[i];
if(current == '(' || current == '{' || current == '['){
stack.push(current);
}
if(current == ')' || current == '}' ||current == ']'){
if(stack.isEmpty()){
return false;
}
char top = stack.peek();
if((current == ']' && top == '[') ||(current == '}' && top == '{') || (current == ')' && top == '(')){
stack.pop();
}else{
return false;
}
}
}
if(stack.isEmpty){
return true;
}else{
return false;
}
}
You are using stack's size as bound instead of stringToCheck's. The stack is initialized just before so your loop is just skipped.
your program is correct except at mentioned comments in below code
public static boolean checkString(char [] stringToCheck){
Deque<Character> stack = new ArrayDeque<Character>();
int n = stringToCheck.length; // take the length of the given char array
for(int i= 0; i < n;i++){
char current = stringToCheck[i];
if(current == '(' || current == '{' || current == '['){
stack.push(current);
}
if(current == ')' || current == '}' ||current == ']'){
if(stack.isEmpty()){
return false;
}
char top = stack.peek();
if((current == ']' && top == '[') ||(current == '}' && top == '{') || (current == ')' && top == '(')){
stack.pop();
}else{
return false;
}
}
}
if(stack.isEmpty()){ // function call of stack isEmpty()
return true;
}else{
return false;
}
}
Use stringToCheck length for the loop instead stack size. Then, stack.isEmpty isEmpty is a method and you forgot the parenthesis.
public static boolean checkString(char [] stringToCheck){
Deque<Character> stack = new ArrayDeque<Character>();
for(int i= 0; i<stringToCheck.length();i++){
char current = stringToCheck[i];
if(current == '(' || current == '{' || current == '['){
stack.push(current);
}
if(current == ')' || current == '}' ||current == ']'){
if(stack.isEmpty()){
return false;
}
char top = stack.peek();
if((current == ']' && top == '[') ||(current == '}' && top == '{') || (current == ')' && top == '(')) {
stack.pop();
}else{
return false;
}
}
}
if(stack.isEmpty()){
return true;
}else{
return false;
}
}

Character stack to check matching brackets no errors but also doesnt appear to do anything

I took a half a year off from programming and now Im just refreshing my memory w super basic little interview questions...and Ive been stuck for 2 days on the first one.. Below is my code can someone just hint to me why the program shows no errors but upon compilation does nothing? It should ignore text characters but Im not even there yet
public class bracketCheck {
public static void main(String[] args) {
Stack <Character> s = new <Character> Stack();
Scanner input = new Scanner(System.in);
String buff;
System.out.println("please enter brackets & text");
buff = input.nextLine();
input.close();
int count = 0;
boolean cont = true;
Character stackTop;
Character current = buff.charAt(count);
do {
if(current == ')' || current== '}' || current== ']') {
s.push(current);
count++;
}
else if(current== '(' || current== '{' || current== '[') {
stackTop = s.pop();
cont = match(stackTop, current);
}
}
while(s.isEmpty() == false /*&& cont =true*/);
if(s.isEmpty())
System.out.println("bout time......");
}
private static boolean match(Character top , Character not) {
if(top == ')' && not == '(')
return true;
else if(top == ']' && not == '[')
return true;
else if(top == '}' && not == '{')
return true;
else
return false;
}
}
I saw some issues in your code, this is my fixed version of it
import java.util.Scanner;
import java.util.Stack;
// use Capital letters in the beginning of class names
public class BracketCheck {
public static void main(String[] args) {
Stack<Character> stack = new Stack<>();
Scanner input = new Scanner(System.in);
String buff;
System.out.println("please enter brackets & text");
buff = input.nextLine();
input.close();
// using java8 makes iterating over the characters of a string easier
buff.chars().forEach(current -> {
// if <current> is an opening bracket, push it to stack
if (current == '(' || current == '{' || current == '[') {
stack.push((char) current);
}
// if <current> is a closing bracket, make sure it is matching an opening
// bracket or alert and return
else if (current == ')' || current == '}' || current == ']') {
if (!match(stack, (char) current)) {
System.out.println("no good");
return;
}
}
});
// if, after we finished iterating the string, stack is empty, all opening
// brackets had matching closing brackets
if (stack.isEmpty()) {
System.out.println("bout time......");
}
// otherwise, alert
else {
System.out.println("woah");
}
}
private static boolean match(Stack<Character> stack, Character closer) {
// if stack is empty, the closer has no matching opener
if (stack.isEmpty()) {
return false;
} else {
// get the most recent opener and verify it matches the closer
Character opener = stack.pop();
if (opener == '(' && closer == ')')
return true;
else if (opener == '[' && closer == ']')
return true;
else if (opener == '{' && closer == '}')
return true;
else
return false;
}
}
}

Verify whether the next char is the same as first char

I found a problem and i tried my logic but i failed to get to the solution.
This is the problem i am trying to solve in java.
For every opening brace (i.e., (, {, or [), there is a matching closing brace (i.e., ), }, or ]) of the same type (i.e., (matches ), { matches }, and [ matches ]). An opening brace must appear before (to the left of) it’s matching closing brace. For example, ]{}[ is not balanced.
No unmatched braces lie between some pair of matched braces. For example, ({[]}) is balanced, but {[}] and [{)] are not balanced.
I want to write java code which would take such a string input of braces and output whether it is balanced or not.
I am not able to apply logic for this kind of code, i tried however it was not even close to expectations. Please provide with some logic. I know this is not a homework completion site but i am stuck on the logic of this problem. a code snippet would be appreciated.
This has nothing to do with java. You need to use a stack to keep track of the order in which you encounter the brackets.
Algorithm-
loop over the input string.
If the current character is an opening bracket, push it in the stack
It it is a closing bracket, pop an element from the stack and if it is not the corresponding opening bracket to the current closing bracket then it is not balanced.
After traversing the string, if there is an opening bracket in the stack then it is not balanced.
Try this.
public static boolean isBalanced(String s) {
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
switch (c) {
case '(': stack.push(')'); break;
case '[': stack.push(']'); break;
case '{': stack.push('}'); break;
case ')': case ']': case '}':
if (stack.isEmpty() || !stack.pop().equals(c))
return false;
break;
}
}
return stack.isEmpty();
}
No switch version:
public static boolean isBalanced(String s) {
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (c == '(')
stack.push(')');
else if (c == '[')
stack.push(']');
else if (c == '{')
stack.push('}');
else if (c == ')' || c == ']' || c == '}')
if (stack.isEmpty() || !stack.pop().equals(c))
return false;
}
return stack.isEmpty();
}
Another way to solve this problem.
This can be solved using Stack Datastructure.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String string = in.next(); //input string -> eg : {{[[(())]]}}
boolean check = Paran(string);
if(check){
System.out.println("YES");
}
else{
System.out.println("NO");
}
}
//function that checks brackets are balanced or not
public static boolean Paran(String string){
//create a stack
Stack<Character> s = new Stack<Character>();
//check if string is empty
//if string is empty then Balanced
if(string.length() == 0){
return true;
}
//if string is not empty, go through each character
for(int i = 0; i< string.length(); i++){
//fetch each character
char current = string.charAt(i);
//check if that character id any of {([
// if yes push on to the stack
if(current == '[' || current == '{' || current == '('){
s.push(current);
}
//check if that character id any of }])
if(current == '}' || current == ']' || current == ')'){
//check stack is empty
//if yes then return false
if(s.isEmpty()){
return false;
}
//else fetch top most item
char pre = s.peek();
if((current == '}' && pre == '{') || (current == ']' && pre == '[') || (current == ')' && pre == '(')){
s.pop();
}
else{
return false;
}
}
}
return s.isEmpty();
}
}
Hope this helps

Java Stack Boolean Output Customization?

So what I have is this slightly modified version of a code that's here a hundred times over for Java Stack Balancing.
import java.util.Stack;
public class Main {
public static String testContent = "{(a,b)}";
public static void main(String args[])
{
System.out.println(balancedParentheses(testContent));
}
public static boolean balancedParentheses(String s)
{
Stack<Character> stack = new Stack<Character>();
for(int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if(c == '[' || c == '(' || c == '{' )
{
stack.push(c);
}else if(c == ']')
{
if(stack.isEmpty()) return false;
if(stack.pop() != '[') return false;
}else if(c == ')')
{
if(stack.isEmpty()) return false;
if(stack.pop() != '(') return false;
}else if(c == '}')
{
if(stack.isEmpty()) return false;
if(stack.pop() != '{') return false;
}
}
return stack.isEmpty();
}
}
What I'd like to do is customize the output such that it would output something like "balanced" or "imbalanced" instead of true/false. Trying to replace return false; with a System.println containing 'balanced' gives me a whole lot of output lines I didn't want. Been searching around here for about an hour and some change and couldn't quite find the answer I was looking for. Any insight?
You could use something like
System.out.println(balancedParentheses(testContent) ? "balanced" : "imbalanced");
OR if you want a method that returns a String wrap the logic in another method
String isBalanced(String expression) {
return balancedParentheses(expression) ? "balanced" : "imbalanced"
}
and in main()
System.out.println(isBalanced(testContent));
Also you could write the code something like this
public static boolean balancedParentheses(String s) {
Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '[' || c == '(' || c == '{') {
stack.push(c);
} else if (c == ']' || c == ')' || c == '}') {
if (stack.isEmpty() || !matches(stack.pop(), c))
return false;
}
}
return stack.isEmpty();
}
private static boolean matches(char opening, char closing) {
return opening == '{' && closing == '}' ||
opening == '(' && closing == ')' ||
opening == '[' && closing == ']';
}

Categories