How to separate recursive string by comma - java

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=,]+=|$)";

Related

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);
}

Matching ONE specific char then another then a minus ( - )

I'am trying to match the following regex:
I have a String: F-F-W-F
i need to write a regex, that checks if the first char is a W or F followed by an - . To check the String F-F-W-F.
This is what i came up with:
if(SBAKTIV.matches("[WF]{1}-[WF]{1}-[WF]{1}-[WF]{1}")) {
SBAKTIVMessageForLog = "SBAKTIV: Okay";
return true;
As mentioned in the comments, your regex is good to go. Or perhaps can be shortened to ([WF]-)*[WF] or ([WF]-){3}[WF].
I'm only posting an answer to provide a non-regex based solution*, in case you end up wanting/needing one of those too:
for (int i = 0; i < word.length(); i++) {
if (i % 2 == 0) {
if (word.charAt(i) != 'F' && word.charAt(i) != 'W') {
return false;
}
} else if (word.charAt(i) != '-') {
return false;
}
}
return true;
Demo
*This is based obviously on the length being ok, not null and so on

Pig Latin Sentence Converter

I am trying a program that translates your sentence into pig latin. Here's the code I have so far:
public class PigLatin {
public static void main(String[] args) {
//Enter text in the quotes of System.ot.println(covertToLatin(" "));
System.out.println(covertToLatin("Type your sentence here."));
}
private static String covertToLatin(String string) {
String end = "";
String delims = "\\s+";
String[] words = string.split(delims);
for (int i = 0; i < words.length; i++) {
if(isVowel(words[i].toLowerCase().charAt(0))) {
end += words[i] + "ay";
} else {
end += words[i].substring(1) + words[i].substring(0, 1) + "ay";
}
}
return end;
}
private static boolean isVowel(char c) {
if (c == 'a')
return true;
if (c == 'e')
return true;
if (c == 'i')
return true;
if (c == 'o')
return true;
if (c == 'u')
return true;
return false;
}
}
It translates "Type your sentence here." to "ypeTayouryayentencesayere.hay" I am stumped as to finding a way to translate my whole sentence. can you please help me translate a whole sentence into pig latin? Also, it would help if you could find a way to make the sentence convert in all caps too.
for upper case, use String.toUpperCase() function
Start by translating one word first and then a complete sentence. For example STACK should print out ACKSTAY. Your program prints out TACKSAY.
Why is this? Let's look at your logic:
for (int i = 0; i < words.length; i++) {
if(isVowel(words[i].toLowerCase().charAt(0))) {
end += words[i] + "ay";
} else {
/*substring(1) is always 1 &&
you add substring(0,1) which is always the interval (0,1) they never change*/
end += words[i].substring(1) + words[i].substring(0, 1) +ay";
}
}
return end.toUpperCase();
}
private static boolean isVowel(char c) {
if ((c == 'a') | (c == 'e') | (c == 'i') | (c == 'o') | (c == 'u'))
return true;
return false;
}
Try writing your algorithm on paper first. For example always using the word stack.
First letter is an s (not a vowel) let's save it in a temp string.
second letter is t ( not a vowel) let's save it in a temp string.
a is a vowel! we print from a onwards + letters in temp + ay
end result = "ack" + "st" + "ay"
abstracting --> substring(i, endOfString) + substring(k,i) + "AY
so you actually need two counters! i,k used to print substring(i,EndOfString) and substring(i,k) which represents the temp array

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

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;
}
}

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.

Categories