I want to check if a String has matching braces, brackets or parenthesis.
For example:
{}
()
[]
I can do it with a stack. I want to do it with recursion. I was reading the answers for a similar question and the replies were recursion mixed in with a stack. An user responded to those answers saying that recursion is also a stack so your recursive method should not have a stack in the parameters -- this makes sense to me.
I have a big problem though, I'm looking through the String backwards and always removing the last position I check until the String is empty so I return true. I can't picture how I will check for the particular parts, braces, brackets or parenthesis without having an extra parameter in my method to hold what I am looking for. Yet I keep thinking there has to be an easier way to do this.
public boolean isBalanced(String in)
{
if(in.isEmpty())
return true;
if(in.charAt(in.length()) == '}')
{
return recIsBalanced(in.substring(0, in.length()));
}
else if(in.charAt(in.length()) == ']')
{
}
return recIsBalanced(in.substring(0, in.length()));
}
Easiest way to solve this problem using recursion is to shrink the string from both directions. You iterate from left and from right until you see . If these do not match, String is not balanced otherwise apply same algorithm for the String enclosed between those braces. Going only from one end will be a lot trickier and you will have to store some state.
EDIT: thanks to DanielFischer. Actually iterate from one side e.g. left until you find a brace(if this brace is not opening one return false). Than iterate from the other side(in this case right) until you find a matching brace. Now the string will be balanced if and only if the substring enclosed within this braces is balanced and the string to the right of the closing bracket are both balanced using recursion.
public static boolean isBalanced(String str) {
if (str.length() == 0) {
return true;
}
if (str.contains("()")) {
return isBalanced(str.replaceFirst("\\(\\)", ""));
}
if (str.contains("[]")) {
return isBalanced(str.replaceFirst("\\[\\]", ""));
}
if (str.contains("{}")) {
return isBalanced(str.replaceFirst("\\{\\}", ""));
} else {
return false;
}
}
Here is a solution, not replacing anything, straight up recursion:
/**
* #param args
*/
public boolean balance(String s, int start, int end)
{
System.out.println("start:"+start + " end" + end);
if (start == s.length()) return end == 0;
if (end<0) return false;
//if (end == s.length()-1) return start == 0;
if (s.charAt(start) == '(')
return balance(s, start+1, end+1);
if (s.charAt(start) == ')')
return balance(s, start+1, end-1);
return balance(s, start+1, end );
}
It can be done by parsing input string. Grammar for this case is:
P -> (P)
P -> [P]
P -> {P}
P -> e (Null)
It is easier to track position what is parsed in a string, and that recursion stack holds what parenthesis to be closed. Here is simple python implementation.
ps = { '{': '}', '(': ')', '[': ']'}
all_ps = set(['{', '}', '(', ')', '[', ']'])
read_position = 0
def _is_balanced( s, closing_par=None ):
global read_position
while read_position < len(s):
if s[read_position] == closing_par:
read_position += 1 # Read closing parenthesis
return True
elif s[read_position] in ps:
read_position += 1 # Read opening parenthesis
if not _is_balanced( s, ps[s[read_position-1]] ):
return False
else:
if s[read_position] not in all_ps:
read_position += 1 # Read non-parenthesis char
else:
return False # It is closing parenthesis, witouh opening before
return closing_par is None # Are we looking for a closing parenthesis?
def is_balanced( s ):
global read_position
read_position = 0 # Reset parsing position
return _is_balanced( s )
boolean isBalanced(String str)
{
if (str.isEmpty()) {
return true;
}
else if (str.charAt(0) == '(') {
return str.charAt(str.length() - 1) == ')'
&& isBalanced(str.substring(1, str.length()));
}
else if (str.charAt(0) == '[') {
return str.charAt(str.length() - 1) == ']'
&& isBalanced(str.substring(1, str.length()));
}
else if (str.charAt(0) == '{') {
return str.charAt(str.length() - 1) == '}'
&& isBalanced(str.substring(1, str.length()));
}
else {
return true;
}
}
Related
I tried to solve a problem in leetcode and im not able to pass all the test cases. I tried to use stack. Whenever there is an open parenthesis, I push it into the stack and whenever there is a close parentheses, I check and pop if the correct open parenthesis is present on the top of the stack.
I check if the stack is empty in the last
Problem statement:
Given a string containing just
the characters '(', ')', '{', '}', '[' and ']', determine if the
input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets. Open
brackets must be closed in the correct order. Note that an empty
string is also considered valid.
Stack<Character> stk = new Stack<Character>();
boolean check = true;
char temp;
if(s.length() == 1)
{
return false;
}
else if(s.length() == 0)
{
return true;
}
else
{
for(int i = 0 ; i < s.length() ; i++)
{
temp = s.charAt(i);
if(temp == '{' || temp == '(' || temp == '[')
{
stk.push(temp);
}
else if(temp == '}')
{
if(stk.peek() == '{')
{
stk.pop();
}
else
{
check = false;
}
}
else if(temp == ')')
{
if(stk.peek() == '(')
{
stk.pop();
}
else
{
check = false;
}
}
else if(temp == ']')
{
if(stk.peek() == '[')
{
stk.pop();
}
else
{
check = false;
}
}
}
if(check == false && stk.empty() == false)
{
return false;
}
else
{
return true;
}
}
You have simply not taken in consideration cases such as
()), where the stack can be empty when you receive a new closing paranthesis.
Simply add
!stk.isEmpty()&&
before each
stk.peek()
It's generally a good idea when working with vectors, matrix, etc. to verify if the element is within bounds and exists(or give internal reasoning as to why it isn't and why at least a check is necessary).
Also, sometimes you can have stuff such as
(, where the check doesn't meet a mismatching closing paranthesis to turn it into false. However, there is a mismatching opening paranthesis.
So the final part of the code has to be
if(check == false || stk.empty() == false)
instead of &&, I put ||
I've run it on the site and it works :) .
This code works on Leetcode. I've modified it so that instead of setting check to false, it just immediately returns false, since there's no point going through the whole string. It also checks if the stack is empty at each iteration. To avoid failing when the input starts with a closing parentheses, square bracket, or curly brace, it pushes the first character of the string onto the stack at the very start.
I've also improved it a bit by rejecting strings of odd lengths at the very start, which makes it run faster than 98.69% of all submissions to the Leetcode problem.
Stack<Character> stk = new Stack<Character>();
char temp;
int len = s.length();
if(len == 0) {
return true;
} else if (len % 2 == 1) {
return false;
}
stk.push(s.charAt(0));
for(int i = 1; i < len; i++) {
temp = s.charAt(i);
switch (temp) {
case '{':
case '(':
case '[':
stk.push(temp);
break;
case '}':
if (stk.peek() == '{') {
stk.pop();
break;
} else return false;
case ')':
if (stk.peek() == '(') {
stk.pop();
break;
} else return false;
case ']':
if (stk.peek() == '[') {
stk.pop();
break;
} else return false;
}
if (stk.isEmpty()) break;
}
return stk.isEmpty();
I hope you don't mind that I replaced your if-statements with a switch block. It's pretty much the same, but it looks clearer to me, at least. You can always change it back though, it'll work the same.
This seems to work fine:
public boolean isValid(String s) {
int n = s.length();
if (n == 0) return true;
if (n % 2 == 1) return false;
Stack<Character> st = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '{' || c == '[' || c == '(') {
st.push(c);
} else if (st.isEmpty()) { // no opening bracket stored
return false;
} else {
char prev = st.pop();
switch(c) { // matching open and close bracket
case '}': if (prev != '{') return false; else break;
case ']': if (prev != '[') return false; else break;
case ')': if (prev != '(') return false; else break;
}
}
}
return st.isEmpty(); // stack must be empty in the end - all pairs matched
}
boolean Match(char c) {
if (this.type == '[' && c == ']')
return true;
if (this.type == '{' && c == '}')
return true;
if (this.type == '(' && c == ')')
return true;
return false;
}
Stack<Bracket> opening_brackets_stack = new Stack<Bracket>();
for (int position = 0; position < text.length(); ++position)
{
char next = text.charAt(position);
if (next == '(' || next == '[' || next == '{')
{
// Process opening bracket, write your code here
Bracket temp = new Bracket(next,position);
opening_brackets_stack.push(temp);
}
if (next == ')' || next == ']' || next == '}')
{
// Process closing bracket, write your code here
try{
Bracket item = opening_brackets_stack.pop();
if(!item.Match(next))
{ //not match
System.out.println(position+1);
return;
}
}
catch(EmptyStackException e){}
}
}
// Printing answer, write your code here
try{
if(opening_brackets_stack.isEmpty())
{
System.out.println("Success");
}
else {
Bracket item = opening_brackets_stack.pop();
//print position of first unmatched opening bracket
System.out.println(item.position+1);
}
}
catch (EmptyStackException e){}
}
i am getting wrong answer in cases like "}","()}" in which bracket is at last position.
i am supposed to get answer "1","3" respectively for above cases but i am getting "Success".
In all other cases, it works perfectly fine.
What should I do?
With a string like "}", your code tries to pop an opening brace from the stack. But the stack is empty so you get an EmptyStackException, and control is transferred to your exception handler. Which does nothing.
Rather than trying to catch an exception, check to see if the stack is empty. If it is, then you know that you have too many closing braces. Treat it the same way you'd treat a false return from item.Match.
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
I am writing a function to fulfill these requirements:
Given a string, return true if it is a nesting of zero or more pairs of parenthesis, like (()) or ((())). Suggestion: check the first and last chars, and then recur on what's inside them.
nestParen("(())") β true
nestParen("((()))") β true
nestParen("(((x))") β false
The correct solution shown on the site is:
public boolean nestParen(String str) {
if (str.equals("")) return true;
if (str.charAt(0) == '(' && str.charAt(str.length()-1) == ')')
return nestParen(str.substring(1,str.length()-1));
else
return false;
}
I don't understand why this works. If the given string has a character other than ( like a ", won't it hit the else case and return false rather than skipping to the next (?
This will definitely not work if the input string contain some thing other than ( and ) to make this work just call another function like below before calling this function:
clean(String str){
String str = "(((X+y)+z))";
String retStr = "";
for(int i = 0 ; i<str.length() ; i++){
if(str.charAt(i) == '(' || str.charAt(i) == ')')
{
retStr += str.charAt(i);
}
}
return retStr
}
and then call your recursive function with input of retStr.
As seems typical with much example code, the suggested correct solution is inadiquate.
Here is an actually correct solution:
public boolean nestParen(final String value)
{
if (value != null)
{
if (value.isEmpty())
{
return true;
}
if (value.charAt(0) == '(' && value.charAt(value.length()-1) == ')')
{
return nestParen(value.substring(1, value.length()-1));
}
else
{
return false;
}
}
else // value is null
{
return true;
}
}
Explanation: (same as with the other answer)
if the parameter is not null, continue. This prevents NullPointerExceptions.
if the parameter is empty, return true. The problem appears to be return true if a string contains zero or more nested pairs of parens and nothing else.
If the first char is '(' and the last char is ')', strip these chars and check again (this is the recursion).
otherwise (first is not '(' and/or last is not ')') return false.
lastly, if the parameter was null, return true (it contains zero pairs and nothing else).
I'm just learning java, and I have an assignment where I have to write a program that checks the validity of expressions about sets. Valid expressions are capital letters, an expression with a tilde in front, and can be combined using + and x as well as with parentheses. I've written a program that almost works, but I can't figure out how to get the binary operators to work with the parentheses.
It may also be that I have approached the problem in the wrong way (trying to validate from left to right, ignoring everything to the left once it's been validated). I can use any help I can get about writing recursive programs for this sort of problem; that is, if you have any pointers for a better way of approaching the problem, that would be incredibly helpful.
For reference, here is the code that I have:
public static boolean check(String expr) {
char spot;
int close=0;
expr = expr.trim();
//base case
if (expr.length() == 1 && expr.charAt(0)>= 'A' && expr.charAt(0) <= 'Z')
return true;
if (expr.charAt(0) == '~') {
if (expr.charAt(1) == 'x' || expr.charAt(1) == '+' || expr.charAt(1) == ')')
return false;
return check(expr.substring(1));
}
if (expr.indexOf('x') > 0 && expr.indexOf('x') > expr.indexOf(')')) {
int x = expr.indexOf('x');
if (check(expr.substring(0, x)) && check(expr.substring(x)))
return true;
}
if (expr.indexOf('+') > 0 && expr.indexOf('+') > expr.indexOf(')')) {
int plus = expr.indexOf('+');
if (check(expr.substring(0, plus)) && check(expr.substring(plus+1)))
return true;
}
if (expr.charAt(0) == '(') {
close = findEnd(expr.substring(1));
if (close < 0)
return false;
if (check(expr.substring(1,close)) && check(expr.substring(close+1)))
return true;
}
return false;
}
I'm not sure why your code is that complex. Recursion for this is pretty simple overall; here's what I'd do:
public static boolean check(String str) {
if(str.equals("")) return true;
if(str.charAt(0).isAlphaNumeric() || str.charAt(0) == '(' || str.charAt(0) == ')') return check(str.substring(1));
return false;
}
Your edge cases are if the string is empty; if this is the case, then the string is valid. If the character doesn't match what you're looking for, return false. Otherwise, check the next character.