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;
}
}
Related
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.
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;
}
I am required to write my own stack using an array which then I have to implement the bracket matching problem.
This is my algorithm: if we're given the string: "(())" it is returning "not balanced" when it should say it is "balanced". If you look over at BracketCheck.java near the end it tests whether the stack is empty where if it is it should return true and say the given string: "(())" is balanced. I am having problems debugging it and the result of the operation is incorrect.
Here is my stack and main class code:
public class Stack {
// instance fields:
private char array[]; // our array
private int topOfStack; // this indicates the value for each position
// overloaded constructor:
public Stack(int size) {
this.array = new char[size]; // here we instantiate a new char type array.
this.topOfStack = -1; // we set the starting position of the topOfStack to -1.
}
// push method:
public void push(char character) {
if(isFull() == true) {
System.out.println("Stack overflow error.");
}
else {
topOfStack++;
array[topOfStack] = character;
}
}
// pop method:
public char pop() {
if(isEmpty() == true) {
//System.out.println("Overflow.");
return '\0';
}
else {
char c = array[topOfStack];
topOfStack--;
return c;
}
}
// top method:
public int top() {
if(isEmpty() == true) {
System.out.println("The stack is empty.");
return 0;
}
else {
return array[topOfStack]; // returns the top element in the stack.
}
}
// size method:
public int size() {
return topOfStack + 1;
}
// isEmpty method:
public boolean isEmpty() {
if(topOfStack == -1) {
return true;
}
else {
return false;
}
}
// isFull method:
public boolean isFull() {
if(topOfStack == array.length -1 ) {
System.out.println("Stack if full.");
return true;
}
else {
return false;
}
}
BracketCheck.java
public class BracketCheck {
public static void main(String args[]) {
String text = "(())";
//boolean check = isBalanced(text);
if(isBalanced(text) == true) {
System.out.println("Balanced.");
}
else {
System.out.println("Not balanced");
}
}
public static boolean isBalanced(String text) {
Stack stack = new Stack(25); // for simplicity our stack is going to be a size of 25.
char[]arr = text.toCharArray(); // convert our string to a set of characters in an array.
// here we are looping through our text
for(int i = 0; i < arr.length; i++) {
if(arr[i] == '{' || arr[i] == '(' || arr[i] == '[') {
stack.push(arr[i]);
}
else if(arr[i] == '}' || arr[i] == ')' || arr[i] == ']') {
if(stack.isEmpty()) {
return false; // if empty then return false.
}
else if((stack.pop() == '(' && arr[i] != ')') || (stack.pop() == '{' && arr[i] != '}') || (stack.pop() == '[' && arr[i] != ']')) {
return false; // here we return false because this tells us that there is a mismatch and not balanced. Also if we did pop out the brace and it was equal
// to it's corresponding closing brace then it will just continue the loop other return false to indicate it is unbalanced.
}
}
}
if(stack.isEmpty()) {
return true; // after looping through the text if the stack turns out to be empty then this shows that there the text is balanced indeed because
}
else {
return false;
}
}
}
In this condition
else if((stack.pop() == '(' && arr[i] != ')') || (stack.pop() == '{' && arr[i] != '}') || (stack.pop() == '[' && arr[i] != ']')) {
You pop 3 times, so you extract 3 different elements from your stack. To fix it, pop once and save popped element in local variable:
if(stack.isEmpty()) {
return false; // if empty then return false.
}
else {
char element = stack.pop();
if((element == '(' && arr[i] != ')') || (element == '{' && arr[i] != '}') || (element == '[' && arr[i] != ']')) {
return false;
}
}
So basically before people start questioning why I'm not using a stack to save time over using counters and stuff.
This is a homework problem working with space complexity, so ignoring time complexity, we are attempting to reduce space complexity.
To do so, I have to use counters to keep track of the brackets.
Possible bracket types: '(' ')' '[' ']'
I've tried some coding but I seem to be having a problem with one of the test strings, and I just can't pinpoint where the problem is happening.
Boolean isWF(String w) {
// maxLevel is found and any variables I'm using has been initialized
for(int i = 0; i < maxLevel; i++) {
x = w.charAt(i);
currentLevel = i;
if(x == '(' || x == '[') {
holder = x; // Store bracket here to check match
savedLevel++;
counter++;
currentLevel++;
for(int j = i+1; j < w.length(); j++) {
x = w.charAt(j);
if(x == '(' || x == '[') {
currentLevel++;
if(currentLevel == savedLevel) {
holder = x;
counter++;
}
}
else if(x == ')' || x == ']') {
if(currentLevel == savedLevel) {
if((holder == '(' && x == ')') || (holder == '[' && x == ']')) {
currentLevel--;
counter--;
}
else
return false;
}
else {
currentLevel--;
}
}
}
}
else if(x == ')' || x == ']') {
counter--;
if(counter < 0) {
return false;
}
}
}
if(counter != 0) {
return false;
}
return true;
}
}
The strings I'm testing:
()[] - expected to be true, actual is true
([)] - expected to be false, actual is false
[([([()])])] - expected to be true, actual is true
([()([])()][()(())]()) - expected to be true, actual is false
([()([])())[()(())]()) - expected to be false, actual is false
Not a direct answer to where is the bug in your approach but the following approach seems to solve your input cases and is much simpler.
Basically you go over the string checking if the next symbol is one you can accept e.g. you can't accept a ) right after a [ and you keep a count of the open/close of brackets. If they ever go negative it means you are missing something.
public static boolean isBalanced(String s) {
int sOpen = 0;
int rOpen = 0;
for(int i = 0; i < s.length() - 1; ++i) {
final char current = s.charAt(i);
final char next = s.charAt(i + 1);
if(!isValidSymbol(current, next)) {
return false;
}
if(current == '(') rOpen++;
else if(current == '[') sOpen++;
else if(current == ')') rOpen--;
else if(current == ']') sOpen--;
if(rOpen < 0 || sOpen < 0) return false;
}
final char lastChar = s.charAt(s.length() - 1);
if(lastChar == '(') rOpen++;
else if(lastChar == '[') sOpen++;
else if(lastChar == ')') rOpen--;
else if(lastChar == ']') sOpen--;
return s.length() > 1 && rOpen == 0 && sOpen == 0;
}
private static boolean isValidSymbol(char from, char to) {
if(from == '(') {
return to == ')' || to == '[' || to == '(' ;
}
else if(from == '[') {
return to == ']' || to == '(' || to == '[';
}
return true;
}
public static void main(String[] args) {
String testInput = "()[]";
assert isBalanced(testInput) : "expected true";
testInput = "([)]";
assert isBalanced(testInput) == false : "expected false";
testInput = "[([([()])])]";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])()][()(())]())";
assert isBalanced(testInput) : "expected true";
testInput = "([()([])())[()(())]()) ";
assert isBalanced(testInput) == false : "expected false";
}
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 == ']';
}