0

Given two strings, my function is supposed to return true if big string is a combination of small string and false otherwise. i.e.

cat and catcatcatcat would return true cat and catdogcatcat would return false

I'm not sure why it is not working or whether my logic is right at all.

public static boolean isCat(String s, String y) {
    int yl= y.length();
    int counter= 0;    

    for (int i= 0; i < s.length(); i++ ) {
        char[] ychar= y.toCharArray();
        char[] subchar= s.substring(counter, counter + yl).toCharArray();
        if (Arrays.equals(ychar, subchar) == true) {
            counter+= yl;
            return true;
        }
    }
    return true;
}
personX
  • 39
  • 6
  • 2
    Is `y` the larger string of the shorter? How are you calling `isCat`? Also combination is just concatenation? – Dani Mesejo Sep 24 '19 at 01:25
  • 1
    You need a [rubber duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging). Also: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173) – Max Vollmer Sep 24 '19 at 01:26
  • well, all `return` statement in your method is returning `true`... – Adrian Shum Sep 24 '19 at 01:45
  • y is the shorter statement. I'm calling it just fine. The problem is in the function itself. Combination is catenation – personX Sep 24 '19 at 02:07

2 Answers2

5

A far easier way to go about it would be to replace() all instances of the substring with an empty string, and check whether the resulting string is empty or not.

public class Test {
    public static void main(String[] args) {
        System.out.println(isCat("catcatcat", "cat")); // "true"
        System.out.println(isCat("cacatcatt", "cat")); // "false"
    }

    public static boolean isCat(String full, String sub) {
        return sub.isEmpty() || !full.isEmpty() && full.replace(sub, "").isEmpty();
    }
}

Alternatively, use a regular expression to check whether the string matches() a multiple of the substring:

public static boolean isCat(String full, String sub) {
    return full.matches("(\\Q" + sub + "\\E)+");
}
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
1

The most efficient way to do this is using regionMatches: this allows you to compare regions of strings without creating new strings:

int a;
for (a = 0; a < s.length(); a += y.length()) {
  if (!s.regionMatches(a, y, 0, y.length()) {
    break;
  }
}
return a == s.length();

regionMatches is effectively just iterating character-by-character; you could write it with a loop:

int a;
outer: for (a = 0; a < s.length(); a += y.length()) {
  if (a + y.length() > s.length()) break;
  for (int b = 0; b < y.length(); ++b) {
    if (s.charAt(a + b) != y.charAt(b)) break outer;
  }
}
return a == s.length();

You could write it with a single loop:

int a = 0;
for (a = 0; a < s.length(); ++a) {
  if (s.charAt(a) != y.charAt(a % y.length()) break;
}
// You could put a check for s.length() % y.length() first,
// since there is no point in looping if that is non-zero
return a == s.length() && (a % y.length()) == 0;
Andy Turner
  • 137,514
  • 11
  • 162
  • 243