Checking if the given String has equally matching parenthesis [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
Found some interesting problem solving questions online and here it is.
You are to check the given String str if they contains matching parenthesis.
Example input: [ ] , [ ( ] ) , { [ ] } , { [ } ] , { [ } ) , { ] }
Example output: EQUAL, EQUAL, EQUAL, EQUAL, NOT EQUAL, NOT EQUAL
I have managed to complete the requirements for this feature using basics, just wondering if there is a better way of doing it?
String str = "{[(])}(){}";
int pairs = 0;
boolean unableToFind = false;
ArrayList<Character> anChar = new ArrayList<Character>();
for (int i = 0; i < str.length(); i++) {
anChar.add(str.charAt(i));
}
if (str.length() % 2 == 0) {
while (pairs != str.length() / 2) {
for (int i = 1; i < anChar.size(); i++) {
char a = (char) anChar.get(0);
char b = (char) anChar.get(i);
if (a == '{' && b == '}' || a == '[' && b == ']' || a == '(' && b == ')') {
anChar.remove(i);
anChar.remove(0);
pairs++;
break;
} else {
if (i == anChar.size() - 1) { // reached end of array
unableToFind = true;
break;
}
}
}
if (unableToFind)
break;
}
if (pairs == str.length() / 2) {
System.out.println("Log#01: The String have balanced parenthesis");
} else {
System.out.println("Log#02: The String do not have balanced parenthesis. (" + pairs + "/" + str.length() / 2 + " pairs found)");
}
} else {
System.out.println("Log#03: The String do not have even numbers of parenthesis");
}

Your approach is overly complex. All you need is three counters - countRound, countSquare, and countCurly. Initialize all three to zero, then walk the string character-by-character. If you see an opening parentheses, increment its counter; if it is a closing parentheses, decrement its corresponding counter. Once the loop is over, all three counters must be at zero; otherwise the numbers of parentheses do not match up.
Note: This does not check that parentheses are balanced, because your example does not require it (i.e. "[(])" produces "EQUAL" even through the input is unbalanced).

Just use a Stack. You need to go over each character in the String, and when you find a closing parenthesis, see if the top of the stack has the appropriate opening parenthesis. The logic would look something like this:
char c = input.charAt(i);
if(c == ')' || c == '}' || c == ']') {
if(stack.isEmpty())
return false;
Character stackTop = stack.pop();
if( (c == ')' && stackTop != '(') ||
(c == '}' && stackTop != '{') ||
(c == ']' && stackTop != '[') )
return false;
} else
stack.push(c);
For cases like "{{}", the stack will contain the first '{' at the end. So check to ensure if it's empty.
Not sure about the example you gave. If for "[ { ( ] } )", result is "EQUAL", when the string clearly isn't balanced, dasblinkenlight has the answer :)

Not as Elegant as the previous answers but it works.
Check if the count in for pair of brackets match.
public class EqualClass {
public static void main(String[] args) {
String input = "[ ] , [ ( ] ) , { [ ] } , { [ } ] , { [ } ) , { ] }";
String[] tokens = input.split(",");
char[] bracketTypes = { '[', '{', '(' };
char[] oppositeBracketType = { ']', '}', ')' };
for (String token : tokens) {
boolean equal = true;
char[] characters = token.toCharArray();
for (int indx = 0; indx < bracketTypes.length; indx++) {
if (EqualClass.Test(characters, bracketTypes[indx]) != EqualClass
.Test(characters, oppositeBracketType[indx])) {
equal = false;
break;
}
}
if (!equal) {
System.out.println(token + " Not Equal");
} else {
System.out.println(token + " Equal");
}
}
}
public static int Test(char[] tokenOfCharacter, char bracketType) {
int count = 0;
for (char character : tokenOfCharacter) {
if (character == bracketType) {
count += 1;
}
}
return count;
}
}

Related

How to separate recursive string by comma

I have recursive string that goes like this,
var1=[[1,2,3], [1,2,3]], var2=true, var3="hello", var4=(var1=[[1,2,3], [1,2,3]], var2=true, var3="hello")
I want to separate the string by commas and desired result is this,
var1=[[1,2,3], [1,2,3]]
var2=true
var3="hello"
var4=(var1=[[1,2,3], [1,2,3]], var2=true, var3="hello")
I have tried this regex, (([a-zA-Z0-9]*)=(.*),?\s?)*, to match the something like this, varx=(), but the complete string was matched.
I also tried to do this by traversing the string but was not able to separate strings like varx="...." because the quotes can contain anythings so there was no way to do this.
public static int fun2(int start_index, String str, int end_index) {
Stack<Character> charStack = new Stack<>();
charStack.add(str.charAt(start_index));
char opp = ' ';
if (str.charAt(start_index) == '(') {
opp = ')';
} else if (str.charAt(start_index) == '[') {
opp = ']';
} else if (str.charAt(start_index) == '[')
while (end_index < str.length() && !charStack.isEmpty()) {
if (str.charAt(end_index) == str.charAt(start_index)) {
charStack.add(str.charAt(start_index));
} else if (str.charAt(end_index) == opp) {
charStack.pop();
}
end_index++;
}
if (charStack.isEmpty()) {
System.out.println("correct");
System.out.println(str.substring(start_index, end_index));
}
return end_index;
// throw error
}
public static void fun(String str) {
int start = 0;
int end = -1;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '=') {
System.out.println("key = " + str.substring(start, end + 1));
start = i + 1;
end = start + 1;
if (str.charAt(start) == '[' || str.charAt(start) == '(' || str.charAt(i) == '"') {
System.out.println("value = ");
end = fun2(start, str, end);
start = end;
i = start;
}
} else if (str.charAt(i) == ',' || str.charAt(i) == ' ') {
start++;
end++;
} else {
end++;
}
}
}
Can anyone suggest any regex or piece of code that will do this for me. Thanks in advance.
To get the matches in the example data, you could match the key part without matching an equals sign.
For the value you can either match from an opening till closing parenthesis, or match until the next key part or end of string.
Note that this pattern does not takes any recursion from the parenthesis or square brackets into account. It depends on matching the parenthesis or using the comma as a separator.
[^\s=,]+=(?:\([^()]*\)|.+?)(?=,\s*[^\s=,]+=|$)
Regex demo
In Java with the doubled backslashes
String regex = "[^\\s=,]+=(?:\\([^()]*\\)|.+?)(?=,\\s*[^\\s=,]+=|$)";

Recursive way to parse a string

I have a string "{x{y}{a{b{c}{d}}}}"
And want to print out recursively.
x
-y
-a
--b
---c
---d
This is what I have so far -
private static void printPathInChild2(String path) {
if (path.length() == 0) {
return;
}
if (path.charAt(0) == '{') {
for (int i = 0; i < path.length(); i++) {
if (path.charAt(i) == '{' && i != 0) {
String t1 = path.substring(0,i);
System.out.println(t1);
printPathInChild2(path.substring(i));
} else if (path.charAt(i) == '}') {
String t2 = path.substring(0, i+1);
System.out.println(t2);
printPathInChild2(path.substring(i+1));
}
}
}
}
Struggling with the termination logic
If you want to add '-' characters that depend on the depth of the nesting, you should pass a second argument to the recursive call, which keeps track of the prefix of '-' characters.
When you encounter a '{', you add a '-' to the prefix.
When you encounter a '}', you remove a '-' from the prefix.
When you encounter any other character, you print the prefix followed by that character.
private static void printPathInChild2(String path,String prefix) {
if (path.length() == 0) {
return;
}
if (path.charAt(0) == '{') {
printPathInChild2(path.substring(1),prefix + "-");
} else if (path.charAt(0) == '}') {
printPathInChild2(path.substring(1),prefix.substring(0,prefix.length()-1));
} else {
System.out.println (prefix.substring(1) + path.charAt(0));
printPathInChild2(path.substring(1),prefix);
}
}
When you call this method with:
printPathInChild2("{x{y}{a{b{c}{d}}}}","");
You get:
x
-y
-a
--b
---c
---d
(I see that in your expected output 'd' has 4 '-'s, but I think it's an error, since 'd' has the same nesting level as 'c', so it should have 3 '-'s).
The method can also be written as follows:
private static void printPathInChild2(String path,String prefix) {
if (path.length() == 0) {
return;
}
char c = path.charAt(0);
if (c == '{') {
prefix = prefix + '-';
} else if (c == '}') {
prefix = prefix.substring(0,prefix.length()-1);
} else {
System.out.println (prefix.substring(1) + c);
}
printPathInChild2(path.substring(1),prefix);
}

How to check String using stack

I have some specific task. We have String like "(()[]<>)" or something familiar with this. A question in my interview qustion was how check either String is correct or incorrect. For example: "()[]<>" - true, "([)" - false, "[(])" - false, "([<>])" - true. Thank you guys very much!
I can' t take what's wrong with my code.
Thank a lot guys!!!
Please help!
import java.util.Stack;
public class Test {
public static void main(String[] args) {
String line = "(<>()[])";
Test test = new Test();
boolean res = test.stringChecker(line);
System.out.println(res);
}
public boolean stringChecker(String line){
boolean result = false;
char letter = '\u0000';
char[] arr = line.toCharArray();
Stack<Character> stack = new Stack();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '(' || arr[i] == '[' || arr[i] == '<') {
stack.push(arr[i]);
}
if(arr[i] == ')' || arr[i] == ']' || arr[i] == '>'){
if(stack.peek() == arr[i]){
result = true;
stack.pop();
}
}
}
return result;
}
}
(0) You are pushing < ( and { but in your peek you are checking for >, ), and }
(1) You are starting with result false and setting it to true on the first successful match. Instead you should start with result true and set it to false on the first failed match.
(2) You should check that the stack is empty when you have run out of characters.
(3) You should check for the stack being empty before you peek.
(4) You might want to check for characters that are not expected.
In addition to #TheodoreNorvell 's explanation here is how an implementation could look like
public boolean stringChecker(String input) {
boolean result = true;
char[] arr = input.toCharArray();
Stack<Character> stack = new Stack<>();
try {
for (int i = 0; result && i < arr.length; i++) {
if (arr[i] == '(' || arr[i] == '[' || arr[i] == '<') {
stack.push(arr[i]);
} else if(arr[i] == ')') {
Character c = stack.pop();
result = c.equals('(');
} else if(arr[i] == ']') {
Character c = stack.pop();
result = c.equals('[');
} else if(arr[i] == '>') {
Character c = stack.pop();
result = c.equals('<');
} else {
// found some char that is not allowed
// here it is not just ignored,
// it invalidates the input
result = false;
}
}
// when the teher is not more chars in the array
// the stack has to be empty
result = result && stack.isEmpty() ;
} catch(EmptyStackException e) {
// found a closing bracket in the array
// but there is nothing on the stack
result = false;
}
return result;
}
#Test
public void stringChecker() {
Assert.assertTrue(stringChecker("[]"));
Assert.assertTrue(stringChecker("[(<>)]"));
Assert.assertFalse(stringChecker("([<>)]"));
Assert.assertFalse(stringChecker(">"));
// invalid char
Assert.assertFalse(stringChecker("<[]e>"));
// stack is not empty
Assert.assertFalse(stringChecker("("));
}
Note that in such a situation a switch-case statement is more elegant than if-else if-else.

Undefined char in output of bracket-matching program using custom stack

My Java Program is below. It's my training exercise. The one implements stack stucture for special type of string parsing(string with delimiter).
This delimiter-matching program works by reading characters from the string one at
a time and placing opening delimiters when it finds them, on a stack. When it reads
a closing delimiter from the input, it pops the opening delimiter from the top of the
stack and attempts to match it with the closing delimiter. If they’re not the same
type (there’s an opening brace but a closing parenthesis, for example), an error
occurs. Also, if there is no opening delimiter on the stack to match a closing one, or
if a delimiter has not been matched, an error occurs. A delimiter that hasn’t been
matched is discovered because it remains on the stack after all the characters in the
string have been read.
I use Eclipse. My output is here:
Please enter String:
{}
ch0 = {
ch1 = }
chLabel1 = **UNDEFINED CHAR(SQUARE WITH QUESTION MARK INSIDE IT)**
Error at }**
Could you explain value of chLabel?
As I understand operator "|" (here, cause two operands have boolean type) - is "lazy", shortcut version of "||" operator. I've tested the program after substitution "|" for "||"-result is the same.
public class MyStack {
private int top=0;
private int maxSize=0;
private char[] charArray=null;
public MyStack(int size){
maxSize=size;
top=0;
charArray=new char[maxSize];
}
public void push(char ch){
charArray[top++]=ch;
}
public char pop(){
return charArray[top--];
}
public boolean isEmpty(){
if(top==0)
return true;
else return false;
}
public boolean isFull(){
if(top==(maxSize-1))
return true;
else return false;
}
}
class StringParse {
private String stringForParsing = null;
public StringParse(String string) {
this.stringForParsing = string;
}
public void parser() {
char[] chArr = stringForParsing.toCharArray();
MyStack mySt = new MyStack(chArr.length);
for (int i = 0; i < chArr.length; i++) {
char ch = chArr[i];
switch (ch) {
case '{':
case '(':
case '[':
mySt.push(ch);
System.out.println("ch" + i + " = " + ch);
break;
case '}':
case ')':
case ']':
if (mySt.isEmpty())
System.out.println("Error at" + ch);
else {
char chLabel = mySt.pop();
System.out.println("ch" + i + " = " + ch);
System.out.println("chLabel" + i + " = " + chLabel);
if ((chLabel == '{') && (ch == '}') | (chLabel == '(') && (ch == ')') | (chLabel == '[') && (ch == ']'))
break;
else {
System.out.println("Error at " + ch);
break;
} // end of second else
} //end of first else
default:
break;
} //end of switch
} //end of parser method
}
} //end of class
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System. in ));
System.out.println("Please enter String:");
String s = br.readLine();
StringParse strP = new StringParse(s);
strP.parser();
}
}
There are two problems:
There's an error with the pop function.
Consider doing one push and then one pop:
top = 0
push
insert at position 0
set top to 1
pop
get position 1 (not set yet!)
set top to 0
You need to use pre-decrement instead of post-decrement, so charArray[top--] should be charArray[--top].
With this change I get chLabel1 = {.
Reiterating what I said in the comments...
| has higher precendence than &&(as opposed to || which has lower precedence) (see this)‌​,
thus a && b | c && d is the same as a && (b | c) && d,
as opposed to a && b || c && d which would be (a && b) || (c && d).
When changing the |'s to ||'s, I no longer get Error at }.
There may be a problem with your MyStack class
Using java.util.Stack gives me no error, just a "chLabel1 = {"
Error at } can be resolved by following Dukeling's advice and using || instead of |:
(chLabel == '{') && (ch == '}') || (chLabel == '(') && (ch == ')') || (chLabel == '[') && (ch == ']')
So, it looks like your code in MyStack.pop() doesn't return a valid char. I'll need to see your MyStack code to help further.

Java Vowel counter using recursion

I'm doing an online CPS course and a question requires me to write a code that counts the vowels(upper and lowercase) in a string. Here is my code:
public static int countVowels( String s )
{
{
if ( s.length() == 0 )
return 0 + countVowels(s);
else if ( (s.substring(0, 1) == "a" ) || (s.substring(0, 1) == "A") )
return 1 + countVowels(s.substring(1));
else if ( (s.substring(0, 1) == "e" ) || (s.substring(0, 1) == "E") )
return 1 + countVowels(s.substring(1));
else if ( (s.substring(0, 1) == "i" ) || (s.substring(0, 1) == "I") )
return 1 + countVowels(s.substring(1));
else if ( (s.substring(0, 1) == "o" ) || (s.substring(0, 1) == "O") )
return 1 + countVowels(s.substring(1));
else if ( (s.substring(0, 1) == "u" ) || (s.substring(0, 1) == "U") )
return 1 + countVowels(s.substring(1));
}
return countVowels(s.substring(1));
}
but I'm getting a "StackOverFlow" error and I'm not sure what to do. I know that the error means that the terminating condition isn't being reached. I'm not allowed to use anything that I haven't learned yet and I'm also not allowed to use for or while statements because this is a recursion problem.
Could I please get some help?
In the case when s.length() == 0 you are causing an infinite recursion. An empty string has 0 vowels, so you should edit 5th line to return 0; Another thing to watch out for: you're comparing strings with ==. This operator is intended for something else. Use equals instead. Take a look at this, for example: String comparison. That is s.substring(0, 1) == "a" should become s.substring(0, 1).equals("a")
As a matter of fact, there are some other pieces of advice I'd give you, like just storing the first letter in the string, instead of calculating it in every case (twice at that). Also, you can get the lower case character for the first character, so that you can reduce the cases you compare to twice. Also, add vowels to an array, this code is not DRY.
This is a possible solution in javascript. You can test it by creating a file 'something.html' and opening it in your browser.
<html>
<head></head>
<body>
<div id="input">
</div>
<div id='answer'>
</div>
<script>
var vowels = ['a','e','i','o','u'];
var testInput = 'Hello this is just a test. Out with it.';
function Contains(value, inArray) {
var found = false;
for(var j=0, size = inArray.length; j < size; j++) {
if(value.toLowerCase() === inArray[j]) {
found = true;
}
}
return found;
}
var vowelCounter = 0;
for(var i=0, j = testInput.length; i < j; i++) {
if(Contains(testInput[i], vowels)) {
vowelCounter +=1;
}
}
var inp = document.getElementById("input");
inp.innerHTML = 'Question <br/>' + testInput;
document.getElementById('answer').innerHTML = 'Number of Vowels: ' + vowelCounter;
</script>
</body>
</html>
I hope by now you would have completed your homework. I have solved the same problem in a shorter way:
public class CountVowels {
private static String vowels = "aeiou";
public static void main(String[] args){
String s = "RohanAskedAQuestion";
System.out.println(recursivelyCountVowels(s));
}
private static int recursivelyCountVowels(String s) {
if(s==null||s.length()==0)
{
return 0;
}
if(vowels.contains((CharSequence) s.substring(0, 1).toLowerCase())){
return 1+recursivelyCountVowels(s.substring(1));
}
return 0+recursivelyCountVowels(s.substring(1));
}
}
I hope it helps :) , I am also learning java so if anybody has any suggestion please do tell.
Thanks.
Maybe its a little late but still :)
public int recursiveCountVowels(String str,int count,int currentPosition)
{
str = str.toLowerCase();
if(str.trim().length() == 0)
return count;
if(currentPosition == str.length())
return count;
for(int i = currentPosition ; i < str.length();i++)
{
if(str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i' || str.charAt(i) == 'o' || str.charAt(i) == 'u')
count++;
currentPosition++;
}
return recursiveCountVowels(str, count, currentPosition);
}
vowel count (vc) - Return the number of vowels in an input string.
public static int vc(String s)
{
if(s.length() - 1 < 0) return 0;
return((("aeiou".indexOf((s.charAt(s.length()-1)+"").toLowerCase()) >= 0 ? 1 : 0))
+ vc((s = s.substring(0,s.length()-1))));
}

Categories