Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

catDog string problem at Codingbat.com

Tags:

java

string

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:

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


2 Answers

While you are pretty close to a solution, there are a few critical problems in your code:

  1. Your call to substring() fetches a string of size 2. That string can never be cat nor dog. Change the second parameter in the method call to i + 3 to get 3 characters.

  2. Your call to substring() will throw an IndexOutOfRangeException, as i approaches 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 your for loop to i < str.length() - 2.

  3. The return value of your method will always be true. In the case where dogAnswer != catAnswer you return exactly that expression - which will resolve to true. A possible solution: Merge the two return statements into return dogAnswer == catAnswer.

Additionally, there are a few things you could do to make your code simpler:

  1. There really is no need to copy cat_Count into catAnswer and dog_Count into dogAnswer. Throw away two of the variables, and use the other pair exclusively.

  2. If the input string is not allowed to contain anything else than cat and dog, your loop can be optimized to only consider every third position in the input string. Change i++ into i += 3. (Update: after seeing the test data used at CodingBat, I can tell that this is not the case.)

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

like image 143
Jørn Schou-Rode Avatar answered May 22 '26 19:05

Jørn Schou-Rode


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.

like image 44
polygenelubricants Avatar answered May 22 '26 18:05

polygenelubricants