'catDog string problem at Codingbat.com
Could anyone check my solution?
I want to return true if the string "cat" and "dog" appear the same number of times in the given string. There are various strings with different numbers of "cat" and "dog".
public boolean catDog(String str)
{
int catAnswer = 0;
int dogAnswer = 0;
int cat_Count = 0;
int dog_Count = 0;
for (int i=0; i< str.length()-1; i++)
{
String sub = str.substring(i, i+2);
if ((sub.equals("cat"))) cat_Count++;
if ((sub.equals("dog"))) dog_Count++;
catAnswer = cat_Count;
dogAnswer = dog_Count;
} //end for
if(dogAnswer == catAnswer ) {return true;}
// else
return (dogAnswer != catAnswer);
}
UPDATE:
If i use i + 3 i get an error code Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 7 (line number:10) - hence i use i + 2 (no errors are reported with it
Changing to i < str.length() - 4 gives a blanket response of true despite some of the test strings containing an unequal number of "cat" & "dog " tokens
The crux of the problem is that the response is either all true or all false when there is variable numbers of "cat" & "dog" in the various strings
the output from the code can be seen at http://codingbat.com/prob/p111624 - catDog string problem
Please try in cutting and pasting my code to see the output - this will explain more graphically than i could say
Solution 1:[1]
While you are pretty close to a solution, there are a few critical problems in your code:
Your call to
substring()fetches a string of size2. That string can never becatnordog. Change the second parameter in the method call toi + 3to get3characters.Your call to
substring()will throw anIndexOutOfRangeException, asiapproaches the end of the length of the input string. Make sure you do not ask for a substring that "overflows" the length of the input string. One way to fix this bug, would be to change the conditional expression in yourforloop toi < str.length() - 2.The return value of your method will always be
true. In the case wheredogAnswer != catAnsweryou return exactly that expression - which will resolve totrue. A possible solution: Merge the tworeturnstatements intoreturn dogAnswer == catAnswer.
Additionally, there are a few things you could do to make your code simpler:
There really is no need to copy
cat_CountintocatAnsweranddog_CountintodogAnswer. Throw away two of the variables, and use the other pair exclusively.If the input string is not allowed to contain anything else than(Update: after seeing the test data used at CodingBat, I can tell that this is not the case.)catanddog, your loop can be optimized to only consider every third position in the input string. Changei++intoi += 3.
After implementing fix #1, #2 and #3 as well as suggestion #1, I have made a test run using the provided test bench, and the result is quite satisfying:
All correct
Solution 2:[2]
int count(String needle, String haystack) {
return haystack.split(needle, -1).length - 1;
}
public boolean catDog(String str) {
return count("dog", str) == count("cat", str);
}
Here's an "All Correct" solution that uses split. The -1 is used to preserve trailing empty strings.
Solution 3:[3]
You will want to iterate each character in your string and then check to see if the substring is equal to either cat or dog and increments the counts.
public boolean catDog(String str) {
int end = str.length();
int cDog = 0;
int cCat = 0;
// We don't need to go to the end because cat/dog are 3 characters long each. So we can avoid extra checks.
for (int i=0; i < end-2; i++) {
if(str.substring(i, i+3).equals("cat")) {
cCat++;
} else if(str.substring(i, i+3).equals("dog")) {
cDog++;
}
}
return cCat == cDog ? true : false;
}
Solution 4:[4]
1. if i use i + 3 i get an error code Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 7 (line number:10) - hence i use i + 2 (no errors are reported with it 2.changing to i < str.length() - 4 gives a blanket response of true despite some of the test strings containing an unequal number of "cat" & "dog " tokens
The crux of the problem is that the response is either all true or all false despite there being a variable numbers of "cat" & "dog" tokens in the various strings
the output from the code can be seen at http://codingbat.com/prob/p111624 - catDog string problem
Please try in cutting and pasting my code to see the output - this will explain more graphically than i could say
Solution 5:[5]
A solution with less duplication would be to write a function that counts occurrences of a substring within a string, then call that function with the string and "cat", and with the string and "dog", and return whether the two counts agree.
Solution 6:[6]
public boolean catDog(String str) {
int cdog = 0;
int ccat = 0;
for (int i = 0; i < str.length()-2; i++)
{
if (str.charAt(i)== 'c' && str.charAt(i+1)== 'a' && str.charAt(i+2)== 't')
{
ccat++;
}
else if(str.charAt(i) == 'd' && str.charAt(i+1)== 'o' && str.charAt(i+2)== 'g')
{
cdog++;
}
}
if (cdog == ccat)
return true;
else
return false;
}
Solution 7:[7]
public boolean catDog(String str) {
boolean x =false; // created a boolean variable.
int cCount=0; // variable to count cat in string.
int dCount=0; // variable to count dog in string.
for(int i =0;i<str.length()-2;i++){
if(str.charAt(i)=='c'&&str.charAt(i+1)=='a'&&str.charAt(i+2)=='t'){ // checking if the string has cat if it does count how many time it has.
++cCount;
}
if(str.charAt(i)=='d'&&str.charAt(i+1)=='o'&&str.charAt(i+2)=='g'){ // checking if the string has dog if it does count how many time it has.
++dCount;
}
}
if(cCount==dCount){ // comparing cat and dog count.
return true;
}
return x;
}
Solution 8:[8]
public boolean catDog(String str) {
int countcat = 0;
int countdog = 0;
if( str.length() >= 3){
for( int i = 0 ; i < str.length()-2 ; i++){
if ( str.substring(i,i+3).equals("cat"))
countcat = countcat + 1;
}
for( int j = 0 ; j < str.length()-2 ; j++){
if ( str.substring(j,j+3).equals("dog"))
countdog = countdog + 1;
}}
if (countdog == countcat )
return true;
return false;
}
Solution 9:[9]
public boolean catDog(String str) {
int cat, dog;
cat = 0;
dog = 0;
for (int i = 0; i < str.length() - 1; i++) {
if ((i + 3) > str.length()) {
break;
}
if (str.substring(i, i + 3).equals("cat")) {
cat++;
}
}
for (int i = 0; i < str.length() - 1; i++) {
if ((i + 3) > str.length()) {
break;
}
if (str.substring(i, i + 3).equals("dog")) {
dog++;
}
}
if (cat == dog) {
return true;
} else
return false;
}
Solution 10:[10]
Here's my answer. It works well. Hope it helps if you're stuck.
public boolean catDog(String str) {
int cat = 0 ;
int dog = 0 ;
for(int i = 0 ; i < str.length()-2; i++){
String temp = str.substring(i,i+3);
if(temp.compareTo("cat")==0)
cat++;
if(temp.compareTo("dog")==0)
dog++;
}
return cat==dog?true:false;
}
Solution 11:[11]
public boolean catDog(String str) {
int count=0;
int flag=0;
for (int i=0; i<str.length()-2; i++)
{
if (str.length()>=3&&str.substring(i,i+3).equals("cat"))
count++;
if (str.length()>=3&&str.substring(i,i+3).equals("dog"))
flag++;
}
if (count==flag)
return true;
else
return false;
}
Solution 12:[12]
public boolean catDog(String str) {
return str.replace("cat","@@").length()==str.replace("dog","&&").length();
}
Solution 13:[13]
My simple python solution:
def cat_dog(str):
cat_sum, dog_sum = 0, 0
for i in range(len(str)-1):
if str[i:i+3] == 'cat':
cat_sum += 1
elif str[i:i+3] == 'dog':
dog_sum += 1
if dog_sum == cat_sum:
return True
else:
return False
Solution 14:[14]
#String-2 > cat_dog(pyton 3)
def cat_dog(str):
c_c=0
c_d=0
for i in range(len(str)-2):
if str[i:i+3]=='cat':
c_c+=1
if str[i:i+3]== 'dog':
c_d+=1
return c_c==c_d
Solution 15:[15]
This helps:
def cat_dog(str):
return str.count('cat')==str.count('dog')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow

