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?
Related
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));
}
}
I have encountered this problem and don't how to solve it.
Complete the following method for determining ifthe parameter contains ONLY the following lower-case characters: d, r, m, f, s, 1 , t. If yes, return true; otherwise, return false.
If the parameter is null or is an empty String, also return true.
public boolean isSonqStrinq(Strinq s){
I have tried the following, but fail:
public boolean isSongString (String s){
int i = 1;
int j = 1;
char a = s.charAt(i);
while (i < s.length()){
{
if(a == 'd' | a == 'r' | a == 'm' | a == 'f' | a == 's' | a == 'l' | a == 't')
j++;
else
break;
}
i++;
}
if (j == s.length())
return true;
else
return false;
}
Can anyone tell me where do I get wrong ?
Because it is an exercise, I think it is better to only provide some good clues. The fun of discovery is better than an all-out spoiler.
Within while (i < s.length()) the condition is always true, and your while loop runs forever.
char a = s.charAt(i) is executed only once, and contains during the whole program execution only the second character of your string.
And why if the exercise states "If the parameter is null or is an empty String, also return true.", would you not try to do that first thing before everything else? That is 50 % of your code completed in 10 secs.
Validating strings is done the easiest with Regular Expressions. String has a particularly interesting method for doing that. Spoiler alert: "^[drmfslt]*$" - no that is not me cussing you in another language :-D
You are comparing the first char every time, you need to move char a = s.charAt(i); inside the while loop.
Also, you can use a for loop here, remove the j counter, and shorten the return statement like so:
public boolean isSongString (String s){
if(s == null) return true;
char[] allowedChars = new char[] {'d','r','m','f','s','l','t'};
for(int i=0; i < s.length(); i++) {
if(Arrays.asList(allowedChars).contains(s.charAt(i)))
continue;
else
return false;
}
return true;
}
EDIT:
JoD.'s answer is best, it allows the solution to be reduced to a single statement:
public boolean isSongString (String s){
return ((s == null) ||
(s.matches("^[drmfslt]*$")));
}
you should intialize i to 0 and and a to ' ' and in while first statement should be
a = s.charAt(i)
this should work fine. If not you can comment back.
public boolean isSongString (String s){
int i = 0;
int j = 0;
while (i < s.length()-1){
char a = s.charAt(i);
if(a == 'd' | a == 'r' | a == 'm' | a == 'f' | a == 's' | a == 'l' | a == 't')
j++;
else
break;
i++;
}
if (j == s.length())
return true;
else
return false;
}
Try this:
import java.io.*;
public class StringTest {
static boolean test(String n){
int l=n.length();
for(int i=0;i<l;i++)
if(n.charAt(i)!='d'&&n.charAt(i)!='r'&&n.charAt(i)!='m'&&n.charAt(i)!='f'&&n.charAt(i)!='s'&&n.charAt(i)!='1'&&n.charAt(i)!='t'&&n.charAt(i)!=' ')
return false;
return true;
}
public static void main(String args[])throws IOException{
boolean n=test("RAHUL");
System.out.println(n);
n=test("drmfs1t");
System.out.println(n);
n=test(" ");
System.out.println(n);
n=test("");
System.out.println(n);
}
}
Output:
false
true
true
true
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;
}
}
}
}
I have a text file with a bunch of words. One part of my program is supposed to, based on the user input, scan this list and insert into the output file the words that contain the requested number of vowels. I have a isVowel method that returns a boolean, but it doesn't seem to work--the output is just an empty list.
Here's the method:
public boolean isVowel(char c)
{
if(c=='a' || c=='A' || c=='e' || c=='E' || c=='i' || c=='I' || c=='o' || c=='O' || c=='u' || c=='U')
{
return true;
}
else
{
return false;
}
}
}
Here's the part of the program where it is used:
public ArrayList<String> vowelHeavy(int n, int m)
{
int vowels = 0;
while(input.hasNextLine())
{
word = input.nextLine();
if (word.length() == n)
{
for(int i = 0; i < word.length(); i++)
{
if(isVowel(word.charAt(i)) == true)
{
vowels++;
}
}
if (vowels == m)
{
output.add(word);
}
}
word = input.nextLine();
}
return output;
}
Your biggest problem is you are not resetting you vowels counting variable when you test a new word. The value just keeps accumulating the total vowels in the file.
Change:
int vowels = 0;
while(input.hasNextLine()) {
...
to:
while(input.hasNextLine()) {
int vowels = 0;
...
As an aside, most of your code, including the isVowel() method, could be eliminated with a single line:
int vowels = word.replaceAll("[^aeiouAEIOU]", "").length();
This works by eliminating from the word all characters that aren't vowels; what's left are the vowels, so just take the length to get the count.
Theres a much easier way to write this code:
public boolean isVowel(char c){
return(your boolean tests);
}
2 things:
If the word.length() == n test is never true, then output is never changed. Please make sure that test is correct.
This statement exists at the top AND bottom of the while loop, causing you to ignore every other input line:
word = input.nextLine();
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();
}