Method to Make Brackets Match - java

I am trying to do a practice problem where I have to write a method that takes a string of curly brackets and returns true if the brackets match up and false if they don’t. If I'm passed the empty string, it needs to return true. We can also assume that the given string can have { and } in it or be empty.
Matching has to be in the correct order of pairs like "{}" not "}{"
These are examples of brackets matching:
{}
{}{}
{{}}
{{{}{{}}}}
These are examples of the brackets not matching:
{
}{
{{}
{{}}}{}
This is what I currently have (Keep in mind I'm relatively new to coding):
public boolean bracketsMatch(String brackets)
{
int count = 0;
if (brackets.length() % 2 == 1){
return false;
}
for(int i = 0; i < brackets.length(); i++){
if ((brackets.charAt(i)+"") == "{"){
count++;
} else if ((brackets.charAt(i)+"") == "}"){
count--;
}
if (count == -1){
return false;
}
}
return count == 0;
}
Inputs like this }{ and {}}{}{ this still dont return the right output.

Your logic works, but the way you're comparing characters is wrong: never use == to compare string values - it tests for reference equality (whether they are the same object). Try brackets.charAt(i) == '{' instead.

Related

Is it possible in java to simplify the following if-statement?

I want to simplify this if-Statement and prevent writing "!='*'" three times. Is it possible?
if (i != '*' && j != '*' && k != '*')
use arrays:put all elements into the array, traverse the array and judge。
List<String> list = new LinkedList<>(Arrays.asList(i,j,k));
if(list.stream().noneMatch("*"::equals)){
}else{
}
use string: splice elements into a string
String temp = i+j+k;
if(temp.contains("*")){
}
I want to simplify this if-Statement and prevent writing "!='*'" three times.
Here is a solution that simplifies the readability and intent.
First, make a simple, obvious method with a clear name (bonus: this is easy to write unit tests around):
private static boolean isValid(char i) {
return i != '*';
}
Then in your calling code, do this:
if (isValid(i) && isValid(j) && isValid(k)) {
// do things if all are valid
}
You can further improve the readability by making a single method which checks isValid() for an array of characters:
private static boolean allAreValid(char[] chars) {
for (char ch : chars) {
if (!isValid(ch)) {
return false;
}
}
return true;
}
Then your calling code becomes really clear, not just the steps but also the intent – proceed with the body of the if statement only if the characters are all valid.
char[] chars = {i, j, k};
if (allAreValid(chars)) {
// do things if all are valid
}
Yes it is possible to omit writing !='*' three times but the method will be still longer one. I would suggest to use the method which you have written in your question but if you really want to try something other out (maybe out of curiosity), you can do this:
char ch[] = {i,j,k}; /*I hope the variables i,j,k in question are char type*/
boolean flag = false;
for(int t = 0; t < ch.length; t++){
if(ch[t] != '*')
flag = true;
else{
flag = false;
break;
}
}
if(flag){
//Tasks to do...
}
Writing this much is a tedious job. Thus, if (i != '*' && j != '*' && k != '*') is the most optimised one. So I would recommend using it.

Beautiful Word:Hackerrank

Question
We consider a word,w , to be beautiful if the following two conditions are satisfied:
No two consecutive characters are the same.
No two consecutive characters are in the following vowel set: a, e, i, o, u, y. Note that we consider y to be a vowel in this challenge.
For example:
The string batman is beautiful because it satisfies the given criteria; however, apple has two consecutive occurrences of the same letter (pp) and beauty has three consecutive vowels (eau), so those words are not beautiful.
My problem is when i am giving an input string "yes" it prints Yes but it should print No.
When i debugged the code using Intellij i see that
It is executing the code which is past return statement but the return statement is used to transfer control to the main function.
Solution
public class Coding {
int count = 0;
public static void main(String[] args) {
Coding obj = new Coding();
Scanner in = new Scanner(System.in);
String w = in .next();
boolean b = true;
char[] c = w.toCharArray();
for (int i = 0; i < c.length - 2; i++) {
b = obj.check(i, c); //recursive function
if (c[i] == c[i + 1]) {
b = false;
break;
}
if (!b) {
System.out.println("No");
break;
}
}
if (c[c.length - 2] == c[c.length - 1]) //check.for.the.remaining.chars
System.out.println("No");
else if (b) {
System.out.println("Yes");
}
}
public boolean check(int i, char[] c) {
if (c[i] == 'a' || c[i] == 'e' || c[i] == 'i' || c[i] == 'o' || c[i] == 'u' || c[i] == 'y') {
count++;
if (count == 2) {
return false; // code following this statement are executing
}
check(i + 1, c);
}
count = 0;
return true;
}
}
You are making a recursive call, but you are ignoring the results of that call!
That doesn't make sense. Either that call is valid, then you should return whatever comes back. Or the recursion doesn't "belong" there, then you should rework the complete method!
Beyond that: although recursive solution often look elegant, those contests focus on optimal performance. Meaning: rather use a single loop to iterate that string once.
Hint: The problem appears to be with method count. It always returns true to main method. If any recursive call returns false, is it being propagated back to main method?

Trying to get the code to check if there are even brackets

I am currently trying to come up with a code that will scan a string
and check to see if there is an even number of open and closing brackets on each line. If so, it would return true. (Excuse me for the incorrectness in formatting but I could not get the examples to properly take shape unless I identified it as code)
{} // The code would return true
{{}}
{}{}
{{{}{{}}}}
} // The code would return false
{}
}}{
{{{}{}
What I tried so far:
public boolean bracketsMatch(String brackets)
{
int lb = 0;
int rb = 0;
int i = 0;
while (brackets.charAt(i) == '{' || brackets.charAt(i) == '}' || brackets.charAt(i) == '')
{
if (brackets.charAt(i) == '{')
{
lb += 1;
}
if (brackets.charAt(i) == '}')
{
rb += 1;
}
if (brackets.charAt(i) == '')
{
if (lb / rb == 2)
{
// Is it possible to get the code scan the next line to next line?
// need an extra statement here for ^^ before I can place the if statement below
if (bracket.charAt(i + 1) == '')
{
return true;
}
}
else
{
return false;
}
}
i++
}
}
I apologize in advance for any experienced programmers as this would be an inefficient nightmare. I am relatively new to programming in general. I attempted to have the code check for the number of left brackets (lb) and right brackets (rb). Whenever the code came to an empty string, it would divide lb by rb. If the code did not equal 2, the code would return false. I probably have more than a dozen errors in this code, but I was wondering if there was any way to have the code go onto the next line to scan the next set of brackets. Thanks for any help in advance.
EDIT 1:
public boolean bracketsMatch(String brackets)
{
int balance = 0;
for (int i = 0; i < brackets.length(); i++)
{
char value = brackets.charAt(i);
if (value == '{')
{
balance += 1;
}
else if (value == '}')
{
balance -= 1;
}
}
if (balance != 0)
{
return false;
}
else
{
return true;
}
}
This won't compile, as '' is an invalid character literal:
if (brackets.charAt(i + 1) == '')
And your current approach of counting opening and closing brackets,
and checking the value of lb / rb won't yield the right result.
You don't need to count the right brackets. You only need to count the open brackets, and reduce that count as they get closed.
Here's a sketch of an algorithm you can use,
I hope to not spoil the exercise:
For each character in the string
If it's an open bracket, increment the count
If it's a close bracket
If the open count is 0, there's nothing to close, so they are not balanced, we can stop
Decrement the count
After all characters, if the open count is 0, the brackets are balanced
As an additional code review note, this is bad in many ways:
if (brackets.charAt(i) == '{') {
// ...
}
if (brackets.charAt(i) == '}') {
// ...
}
What's bad:
Calling brackets.charAt(i) repeatedly is unnecessary if the result will always be the same. Call it once and save the result in a variable.
The two if conditions are exclusive: if the first is true, the second won't be true, so it's pointless to evaluate it. The second condition should be if else instead of if. And instead of an if-else chain, a switch could be more interesting here.
Instead of calling the string brackets, it would be better to call it something more general. What if the actual input is "{something}"? Then it contains more than just brackets, but the algorithm would work just the same. Calling it brackets is misleading.
Alternative way to do
You can use Java Stack class [As it represent the List-In-First-Out stack of object].You can use the push and pop method of Stack class. Here is the implementation.
public class BracketMatching {
public static boolean bracketMatch(String input){
Stack<Character> st = new Stack<>();
for(char c : input.toCharArray()){
if( c == '{')
st.push(c);
else if(c == '}'){
if(st.isEmpty())
return false;
st.pop();
}
}
if(st.isEmpty())
return true;
return false;
}
public static void main(String[] args){
String input1 = "{}{{}}{}{}{{{}{{}}}}";
String input2 = "}{}}}{{{{}{}";
System.out.println(bracketMatch(input1));
System.out.println(bracketMatch(input2));
}
}

Java if-statement being skipped

The method below takes in a string and a pattern and returns true if they match each other. A '.' matches 1 char and a '*' matches 0 or more (e.g. expMatch("abc", "a.c") should return true). I added a bunch of print statements to see where I went wrong and it seems like the if statement is being skipped even if the str.length() == 1.
I call it with System.out.println(expMatch("abc", "a*c"));
Here is the code:
public static boolean expMatch(String str, String pat)
{
if (str.charAt(0) == pat.charAt(0) || pat.charAt(0) == '.')
{
System.out.println("in if");
System.out.println(str.charAt(0));
System.out.println(pat.charAt(0));
System.out.println(str.length());
if (str.length() == 1)
return true;
expMatch(str.substring(1), pat.substring(1));
}
else if (pat.charAt(0) == '*')
{
System.out.println("in else");
System.out.println(str.charAt(0));
System.out.println(pat.charAt(0));
if (str.length() == 1)
return true;
if (str.charAt(0) == pat.charAt(1)) //val of * = 0
expMatch(str, pat.substring(1));
else if (str.charAt(1) ==pat.charAt(1))
expMatch(str.substring(1), pat.substring(1));
}
return false;
}
and the output is:
in if
a
a
3
in else
b
*
in if
c
c
1
false
Even if the length is 1 it skips the if? Any idea why?
P.S. I'm not looking for the solution, just why the if statement is being skipped.
You always return false from the method at the very end. You are calling expmatch recursively but never using the return value. The code comes in to the first if, recurses (because length is not 1) and upon returning will go to the final return statement which returns false.
You need to add a return before your expMatch() calls - because the false comes from your last line return false;
What happens is this:
you call expMatch() with the two Strings.
you enter the if clause
the if clause enters expMatch() recursively
you enter the else clause
the else clause enters expMatch() recursively
you enter the if clause again
you leave the expMatch() method
you leave the other expMatch method
false is returned
Your approach is logically incorrect even if you apply the fixes the others suggested. Try this test case:
System.out.println(expMatch("abddddc", "a*c"));
This is because when you encounter a * in the pattern, you have no way to know how many characters "to eat" from the search string.
To say the least, you need a loop somewhere, not just an if. Let me try to fix it for you (not sure if it's possible though, not sure if you always know which path to take, I mean in your recursion). Think some more about it. Here is another unpleasant test case:
System.out.println(expMatch("adddcac", "a*c"));
// the * needs to eat dddca (despite the c present in dddca),
// it should not stop recursing there at that c
I think you need some sort of full search here.
Just an if or a while loop is not good enough.
EDIT: Here is a fixed version with a bunch of nasty tests. I think this is called non-linear recursion (as it's not a single path you try). Not 100% sure though about that term.
public class Test055 {
public static void main(String[] args) {
// System.out.println(expMatch("abddddc", "a*c"));
System.out.println(expMatch("adcax", "a*c"));
System.out.println(expMatch("adcax", "a*c*"));
System.out.println(expMatch("adcacm", "*"));
System.out.println(expMatch("adcacmmm", "a*c"));
System.out.println(expMatch("adcacmmmc", "a*c"));
System.out.println(expMatch("adcac", "a*c"));
System.out.println(expMatch("adcacxb", "a*c.b"));
System.out.println(expMatch("adcacyyb", "a*c.b"));
System.out.println(expMatch("adcacyyb", "a*c*b"));
}
public static boolean expMatch(String str, String pat)
{
// System.out.println("=====================");
// System.out.println("str=" + str);
// System.out.println("pat=" + pat);
if (pat.length() == 0 && str.length() > 0) {
return false;
} else if (pat.length() == 0 && str.length() == 0) {
return true;
} else if (pat.charAt(0) == '.'){
return str.length() >= 1 && expMatch(str.substring(1), pat.substring(1));
}else if (pat.charAt(0) != '*'){
return str.length() >= 1 && pat.charAt(0) == str.charAt(0) && expMatch(str.substring(1), pat.substring(1));
}else{
// Now let's handle the tricky part
// (1) Look for the 1st non-star in pattern
int k=-1;
char ch = ' ';
for (int i=0; i<pat.length(); i++){
if (pat.charAt(i) != '*'){
k = i;
ch = pat.charAt(k);
break;
}
}
if (k==-1){
// (2A) only stars found in pattern, OK, any str matches that
return true;
}else{
// (2B) do full search now checking all
// possible candidate chars in str that
// match the char ch from pattern
for (int i=0; i<str.length(); i++){
if (str.charAt(i)==ch){
boolean b = expMatch(str.substring(i+1), pat.substring(k+1));
if (b) return true;
}
}
return false;
}
}
}
}

Writing a method to remove vowels in a Java String [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I am a beginner of programming, and am writing a Java method to remove vowel in Strings, but I do not know how to fix this error: ";" expected :
public String disemvowel(String s) {
boolean isVowel(char c);
if (c == 'a') {
return true;
} else if if (c == 'e') {
return true;
} else if if (c == 'i') {
return true;
} else if if (c == 'o') {
return true;
} else if if (c == 'u') {
return true;
}
String notVowel = "";
int l = s.length();
for (int z = 0; z <= l; z++) {
if (isVowel == "false") {
char x = s.charAt(z);
notVowel = notVowel + x;
}
}
return notVowel;
}
String str= "Your String";
str= str.replaceAll("[AEIOUaeiou]", "");
System.out.println(str);
A much simpler approach would be to do the following:
String string = "A really COOL string";
string = string.replaceAll("[AaEeIiOoUu]", "");
System.out.println(string);
This will apply the regular expression, [AaEeIiOoUu] to string. This expression will match all vowels in the character group [AaEeIiOoUu] and replace them with "" empty string.
You've got a lot of syntax errors.
boolean isVowel(char c); - not sure what you're doing with this. if you want it as a separate method, separate it out (and don't place a semicolon after it, which would be invalid syntax.
else if if is invalid syntax. If you're doing an else if, then you only need the one if.
Even if the code would compile, for (int z = 0; z <= l; z++) will cause you to step off of the String. Remove the <= in favor of <.
isVowel == "false" is never going to work. You're comparing a String to a boolean. You want !isVowel instead.
Putting the syntax errors aside, think of it like this.
You have a string that contains vowels. You wish to have a string that doesn't contain vowels.
The most straightforward approach is to iterate over the String, placing all non-vowel characters into a separate String, which you then return.
Interestingly enough, the half-method you have there can accomplish the logic of determining whether something is or isn't a vowel. Extract that to its own method. Then, call it in your other method. Do take into account capital letters though.
I leave the rest as an exercise to the reader.
Here is your code, without changing any logic, but unscrambling the isVowel method:
public String disemvowel(String s) {
// Removed the "isVowel" method from here and moved it below
String notVowel = "";
int l = s.length();
for (int z = 0; z <= l; z++) {
// Note that the "isVowel" method has not been called.
// And note that, when called, isVowel returns a boolean, not a String.
// (And note that, as a general rule, you should not compare strings with "==".)
// So this area needs a lot of work, but we'll start with this
boolean itIsAVowel = isVowel(s.charAt(z));
// (I made the variable name "itIsAVowel" to emphasize that it's name has nothing to do with the method name.
// You can make it "isVowel" -- the same as the method -- but that does not in any way change the function.)
// Now take it from there...
if (isVowel == "false") {
char x = s.charAt(z);
notVowel = notVowel + x;
}
}
return notVowel;
}
// You had this line ending with ";"
boolean isVowel(char c) {
if (c == 'a') {
return true;
// Note that you coded "if if" on the lines below -- there should be only one "if" per line, not two
} else if if (c == 'e') {
return true;
} else if if (c == 'i') {
return true;
} else if if (c == 'o') {
return true;
} else if if (c == 'u') {
return true;
}
// You were missing this final return
return false;
}
(Yes, I know this should be a comment, but you can't put formatted code in a comment.)
You could try something like this:
public static String removeVowels(final String string){
final String vowels = "AaEeIiOoUu";
final StringBuilder builder = new StringBuilder();
for(final char c : string.toCharArray())
if(vowels.indexOf(c) < 0)
builder.append(c);
return builder.toString();
}

Categories

Resources