I am trying to solve this leetcode problem:
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.
I think I am almost correct and have been working on this problem for a long time but couldn't get the correct output especially a case where input is "())".
class Solution {
public boolean isValid(String s) {
Stack<Character> c = new Stack<>();
int n = s.length();
boolean bool = false;
if (s.isEmpty() | s == null) { // Correct
return true;
}
for (int i=0 ; i<n ; i++) {
if (s.charAt(i) == '{') {
c.push('{');
} else if (s.charAt(i) == '[') {
c.push('[');
} else if (s.charAt(i) == '(') {
c.push('(');
} else if (s.charAt(i) == '}' & c.peek() == '{') {
c.pop();
} else if (s.charAt(i) == ']' & c.peek() == '[') {
c.pop();
} else if (s.charAt(i) == ')' & c.peek() == '(') {
c.pop();
} else {
break;
}
}
if (c.isEmpty()) {
return true;
} else {
return false;
}
}
}
I think you should check stack's size before process these conditions.
else if (s.charAt(i) == '}' & c.peek() == '{') {
c.pop();
} else if (s.charAt(i) == ']' & c.peek() == '[') {
c.pop();
} else if (s.charAt(i) == ')' & c.peek() == '(') {
c.pop();
}
The problem is that you are not adding the closure brackets to the stack, so your check of the stack size at the end returns false results.
You could change your ifs to already return false when a open bracket is missing i.e.
else if (s.charAt(i) == '}') {
if(c.peek() == '{'){
c.pop();
}
else{
return false;
}
}
The others would need to be changed similarly.
Thank you all for your suggestions.
I figured out that I should check whether the stack is empty or not before using peek().
else if (s.charAt(i) == '}') {
if (!c.isEmpty() && c.peek() == '{') {
c.pop();
}
else {
return false;
}
In case someone is looking for the javascript solution.
var isValid = function (s) {
// Stack to store left symbols
const leftSymbols = [];
// Loop for each character of the string
for (let i = 0; i < s.length; i++) {
// If left symbol is encountered
if (s[i] === '(' || s[i] === '{' || s[i] === '[') {
leftSymbols.push(s[i]);
}
// If right symbol is encountered
else if (s[i] === ')' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '(') {
leftSymbols.pop();
} else if (s[i] === '}' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '{') {
leftSymbols.pop();
} else if (s[i] === ']' && leftSymbols.length !== 0 && leftSymbols[leftSymbols.length - 1] === '[') {
leftSymbols.pop();
}
// If none of the valid symbols is encountered
else {
return false;
}
}
return leftSymbols.length === 0;
};
Try this once->
var isValid = function (s = "{[]}") {
const leftSymbols = [];
for (let i = 0; i < s.length; i++) {
if (s[i] === "(" || s[i] === "{" || s[i] === "[") {
leftSymbols.push(s[i]);
} else if (
s[i] === ")" &&
leftSymbols.length !== 0 &&
leftSymbols[leftSymbols.length - 1] === "("
) {
leftSymbols.pop();
} else if (
s[i] === "}" &&
leftSymbols.length !== 0 &&
leftSymbols[leftSymbols.length - 1] === "{"
) {
leftSymbols.pop();
} else if (
s[i] === "]" &&
leftSymbols.length !== 0 &&
leftSymbols[leftSymbols.length - 1] === "["
) {
leftSymbols.pop();
} else {
return false;
}
}
return leftSymbols.length === 0;
};
console.log(isValid());
In case someone is looking for the java solution:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i=0; i<s.length(); i++){
char strChar = s.charAt(i);
if(stack.empty()){
stack.push(strChar);
} else{
char stkChar = (char) stack.peek();
if(stkChar == '(' && strChar ==')' ){
stack.pop();
} else if(stkChar == '{' && strChar=='}'){
stack.pop();
} else if(stkChar == '[' && strChar == ']'){
stack.pop();
} else{
stack.push(strChar);
}
}
}
return (stack.empty() ? "true" : "false");
}
Related
can someone help me with this code it is not working with this test case{(([])[])[]]}.
package myProject;
import java.util.*;
public class bracketBalancing {
public static void main (String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("Enter String");
String s=sc.next();
Stack<Character> stack=new Stack<Character>();
if(s.length()==0)
System.out.println("string is empty");
else {
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(ch=='('||ch=='{'||ch=='['){
stack.push(ch);
}
else if(ch==')'&& stack.peek()=='('){
stack.pop();
}
else if(ch=='}'&& stack.peek()=='{'){
stack.pop();
}
else if(ch==']'&& stack.peek()=='['){
stack.pop();
}
}
}
if(stack.empty()){
System.out.println("YES");
}
else{
System.out.println("No");
}
sc.close();
}
}
You should add the else condition to print No if you are neither able to push not pop. Because in that condition it means you have some additional closing brackets which will lead to unbalanced.
Code:
if (s.length() == 0) {
System.out.println("string is empty");
} else {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(' || ch == '{' || ch == '[') {
stack.push(ch);
} else if (ch == ')' && stack.peek() == '(') {
stack.pop();
} else if (ch == '}' && stack.peek() == '{') {
stack.pop();
} else if (ch == ']' && stack.peek() == '[') {
stack.pop();
} else {
System.out.println("No");
stack = null;
break;
}
}
}
if(stack != null) {
if (stack.empty()) {
System.out.println("YES");
} else {
System.out.println("No");
}
}
I'm trying to do a balancing string test. It's very annoying that even I pushed an element into the stack: stack.push(s.charAt(0)), it still says EmptyStackException at Stack.StackTest.main(StackTest.java:18). Here's my code:
import java.util.Stack;
public class StackTest
{
public static void main (String[] args)
{
//Scanner scanner = new Scanner(System.in);
Stack<Character> stack = new Stack<>();
int i;
String s = "{}(){}{}{}";
stack.push(s.charAt(0));
for (i = 1;i < s.length();i++)
{
if (stack.peek() == '{' && s.charAt(i) == '}')
{
if (!stack.empty())
{
stack.pop();
}
}
else if (stack.peek() == '[' && s.charAt(i) == ']')
{
if (!stack.empty())
{
stack.pop();
}
}
else if (stack.peek() == '(' && s.charAt(i) == ')')
{
if (!stack.empty())
{
stack.pop();
}
}
else
{
stack.push(s.charAt(i));
}
}
while (!stack.empty())
{
System.out.print(stack.pop());
}
}
}
Your stack is not empty at the first iteration of the loop, but that first iteration pops the only element from the stack. Then, when in the next iteration you call stack.peek(), you get the EmptyStackException.
You should put the !stack.empty() condition prior to the stack.peek() statement in order to avoid the EmptyStackException.
For example, change
if (stack.peek() == '{' && s.charAt(i) == '}')
{
if (!stack.empty())
{
stack.pop();
}
}
to
if (!stack.isEmpty() && stack.peek() == '{' && s.charAt(i) == '}')
{
stack.pop();
}
You should change your other conditions the same way.
private DSAQueue parseInfixToPostfix(String equation) {
String result = "";
char operator = ' ';
DSAStack stack = new DSAStack();
DSAQueue queue = new DSACircular();
for (int i = 0; i < equation.length(); i++) {
char c = equation.charAt(i);
if (Character.isLetterOrDigit(c)) {
result += c;
}
else if (c == '(') {
stack.push(c);
}
else if (c == ')') {
while (!stack.isEmpty() && stack.top() != '(') {
result += stack.pop();
}
if (!stack.isEmpty() && stack.top() != '(') {
result = "Invalid expression";
}
else {
stack.pop();
}
}
else { //when meets operator
while (!stack.isEmpty() && (precedenceOf(c) <= precedenceOf((char) stack.top()))) {
if (stack.top() == '(') {
result = "Invalid expression";
}
result += stack.pop();
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
if (stack.top() == '(') {
result = "Invalid";
}
result += stack.pop();
}
queue.enqueue(result);
return queue;
}
Above is my code for converting infix to postfix. The example i used is "4+2" and what i got is:
Pushed: 43
Popped: 43
Enqueued: 4243
i dont know why it automatically converted "+" to 43, but i want to store the operator as the operator like "+" in the queue. Is it possible? Or is there an error? because i cant find out what the error is. thank you
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Please help in this regard, the error is shown as empty stack exception.
Code:
import java.util.Stack;
public class Stacks {
public static void main(String[] arg)
{
String s[] = {"5 + ) * ( 2",
// " 2 + ( - 3 * 5 ) ",
"(( 2 + 3 ) * 5 ) * 8 ",
"5 * 10 + ( 15 - 20 ) ) - 25",
" 5 + ( 5 * 10 + ( 15 - 20 ) - 25 ) * 9"
};
for (int i = 0; i < s.length; i++)
{
Arithmetic a = new Arithmetic(s[i]);
if (a.isBalance())
{
System.out.println("Expression " + s[i] + " is balanced\n");
a.postfixExpression();
System.out.println("The post fixed expression is " + a.getPostfix());
a.evaluateRPN();
}
else
System.out.println("Expression is not balanced\n");
}
}
private static class Arithmetic {
String str = "";
Stack<Character> stack = new Stack<>();
String postFix = "";
public Arithmetic(String str)
{
this.str = str;
this.postFix = postFix;
}
private boolean isBalance()
{
Stack<Character> stack = new Stack<>();
for(int i = 0; i < str.length(); i++)
{
if(str.charAt(i) == '(' )
stack.push(str.charAt(i));
else if(str.charAt(i) == ')')
{
if(stack.isEmpty() || stack.pop() != '(')
return false;
}
}
return stack.isEmpty();
}
private void evaluateRPN() {
}
private String getPostfix() {
return postFix;
}
#SuppressWarnings("empty-statement")
private void postfixExpression() {
Stack<Character> stack = new Stack<>();
for(int i = 0; i < str.length(); i++)
{
if(Character.isDigit(str.charAt(i)))
postFix += " " + str.charAt(i);
else if(str.charAt(i) == '+' || str.charAt(i) == '-' ||
str.charAt(i) == '*' || str.charAt(i) == '/' ||
str.charAt(i) == '%' || str.charAt(i) == '(' ||
str.charAt(i) == ')' )
{
do{
stack.push(str.charAt(i));
}
while(stack.isEmpty());
}
if(str.charAt(i) == '(' || str.charAt(i) == ')')
{
if(str.charAt(i) == '(')
stack.push(str.charAt(i));
else if(str.charAt(i) == ')')
{
do
{
do{
postFix += stack.pop();
}while(stack.pop() != ')');
}while(!stack.empty());
}
}
if(str.charAt(i) == '+' || str.charAt(i) == '-' ||
str.charAt(i) == '*' || str.charAt(i) == '/' )
{
if(str.charAt(i) == '+' || str.charAt(i) == '-')
{
do{
postFix += stack.pop();
}while ((stack.pop() != '(') || !stack.empty());
postFix += str.charAt(i);
}
if(str.charAt(i) == '*' || str.charAt(i) == '/')
{
if(stack.pop() == '+' || stack.pop() == '-')
{
stack.push(str.charAt(i));
}
}
}
}
do{
postFix += stack.pop();
}while(!stack.empty());
}
}
}
When you testing use peek function otherwise you are removing the item. When you do :
if(stack.pop() == '+' || stack.pop() == '-')
and your stack contains [*]
When you call stack.pop() you remove * and your stack will be empty after that and you will get exception in second test (stack.pop() == '-').
You need to verify your code and change your logic.
This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I am supposed to write a program to convert infix to postfix. It works for some, but other times not correctly. Especially on infix expressions containing parantheses. Could anyone give me a clue why this is wrong? For example, the infix expression
( ( 5 + 5 * ( 6 - 2 ) + 4 ^ 2 ) * 8 )
returns 5562-*42^++8*((2.
import java.io.*;
import java.util.Scanner;
public class InfixToPostfix
{
//class attributes
private char curValue;
private String postfix;
private LineWriter lw;
private ObjectStack os;
//constructor
public InfixToPostfix(LineWriter l, ObjectStack o)
{
curValue = ' ';
lw=l;
os=o;
}
public String conversion(String buf)
{
String temp =" ";
StringBuffer postfixStrBuf= new StringBuffer(temp);
char popped= new Character(' ');
char topped=' ';
for (int i=0; i<buf.length(); i++)
{
curValue= buf.charAt(i);
if (curValue == '(')
os.push(curValue);
if (curValue == ')')
{
while (popped != '(')
{
popped = ((Character)os.pop());
if (popped != '(')
postfixStrBuf.append(popped);
}
}
if (isOperator(curValue))
{
if( os.isEmpty())
os.push((Character)(curValue));
else
topped=((Character)os.top());
if ( (priority(topped)) >= (priority(curValue)) && (topped != ' ') )
{
popped = ((Character)os.pop());
if (popped != '(')
postfixStrBuf.append(popped);
//if it is a left paranthess, we want to go ahead and push it anyways
os.push((Character)(curValue));
}
if ( (priority(topped)) < (priority(curValue)) && (topped != ' ') )
os.push((Character)(curValue));
}
else if (!isOperator(curValue) && (curValue != ' ') && (curValue != '(' ) && (curValue != ')' ))
postfixStrBuf.append(curValue);
}
//before you grab the next line of the file , pop off whatever is remaining off the stack and append it to
//the infix expression
getRemainingOp(postfixStrBuf);
return postfix;
//postfixStrBuf.delete(0, postfixStrBuf.length());
}
public int priority(char curValue)
{
switch (curValue)
{
case '^': return 3;
case '*':
case '/': return 2;
case '+':
case '-': return 1;
default : return 0;
}
}
public boolean isOperator(char curValue)
{
boolean operator = false;
if ( (curValue == '^' ) || (curValue == '*') || (curValue == '/') || (curValue == '+' ) || (curValue == '-') )
operator = true;
return operator;
}
public String getRemainingOp(StringBuffer postfixStrBuf)
{
char popped=' ';
while ( !(os.isEmpty()) )
{
opped = ((Character)os.pop());
postfixStrBuf.append(popped);
}
postfix=postfixStrBuf.toString();
return postfix;
}
}
I will only post how the inner loop should look like (without the castings everywhere):
if (curValue == '(') {
os.push(curValue);
} else if (curValue == ')') {
if(!os.isEmpty()) {
topped = os.pop();
while (!os.isEmpty() && (topped != '(')) {
postfixStrBuf.append(topped);
topped = os.pop();
}
}
} else if (isOperator(curValue)) {
if (os.isEmpty()) {
os.push(curValue);
} else {
while(!os.isEmpty() && (priority(os.top()) >= priority(curValue))) {
popped = os.pop();
postfixStrBuf.append(popped);
}
os.push(curValue);
}
} else if (curValue != ' ') {
postfixStrBuf.append(curValue);
}
Disclosure: it is pretty late already so I hope it is fine. You should fix the way variables are initialized and return of the getRemainingOp method.