1

I wrote the following Java code, to find the intersection between the prefix and the suffix of a String in Java.

// you can also use imports, for example:
// import java.math.*;
import java.util.*;
class Solution {
    public int max_prefix_suffix(String S) {
        if (S.length() == 0) {
            return 1;
        }
        // prefix candidates
        Vector<String> prefix = new Vector<String>();
        // suffix candidates
        Vector<String> suffix = new Vector<String>();
        // will tell me the difference
        Set<String> set = new HashSet<String>();

        int size = S.length();
        for (int i = 0; i < size; i++) {
            String candidate = getPrefix(S, i);
            // System.out.println( candidate );
            prefix.add(candidate);
        }

        for (int i = size; i >= 0; i--) {
            String candidate = getSuffix(S, i);
            // System.out.println( candidate );
            suffix.add(candidate);
        }

        int p = prefix.size();
        int s = suffix.size();
        for (int i = 0; i < p; i++) {
            set.add(prefix.get(i));
        }
        for (int i = 0; i < s; i++) {
            set.add(suffix.get(i));
        }

        System.out.println("set: " + set.size());
        System.out.println("P: " + p + " S: " + s);
        int max = (p + s) - set.size();
        return max;
    }

    // codility
    // y t i l i d o c
    public String getSuffix(String S, int index) {
        String suffix = "";
        int size = S.length();
        for (int i = size - 1; i >= index; i--) {
            suffix += S.charAt(i);
        }

        return suffix;
    }

    public String getPrefix(String S, int index) {
        String prefix = "";
        for (int i = 0; i <= index; i++) {
            prefix += S.charAt(i);
        }

        return prefix;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        String t1 = "";
        String t2 = "abbabba";
        String t3 = "codility";

        System.out.println(sol.max_prefix_suffix(t1));
        System.out.println(sol.max_prefix_suffix(t2));
        System.out.println(sol.max_prefix_suffix(t3));

        System.exit(0);
    }
}

Some test cases are:

String t1 = "";
String t2 = "abbabba";
String t3 = "codility";

and the expected values are:

1, 4, 0

My idea was to produce the prefix candidates and push them into a vector, then find the suffix candidates and push them into a vector, finally push both vectors into a Set and then calculate the difference. However, I'm getting 1, 7, and 0. Could someone please help me figure it out what I'm doing wrong?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
cybertextron
  • 10,547
  • 28
  • 104
  • 208
  • Somewhat unrelated, but see: http://stackoverflow.com/questions/1386275/why-is-java-vector-class-considered-obsolete-or-deprecated – NullUserException Nov 04 '12 at 17:16
  • 4
    What is it with students and `Vector`??? Are course notes *ever* updated? (You should never use `Vector` - it is broken!) – Bohemian Nov 04 '12 at 17:18
  • 2
    "abbabba" is a palindrome, so every prefix is a suffix. Why isn't the expected value 7? – Ted Hopp Nov 04 '12 at 17:18
  • @NullUserException I found a fix for my code, but it's not the final solution ... – cybertextron Nov 04 '12 at 17:18
  • 1
    Also, you *are* aware that Java has a [`substring()`](http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#substring%28int%29) method, right? And that `Set` does have an [`addAll()`](http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Set.html#addAll%28java.util.Collection%29) method? I see a lot of wheels being reinvented in your code... – NullUserException Nov 04 '12 at 17:19
  • @TedHopp And why is a blank string `""` `1`? Shouldn't it be `0`? – Bohemian Nov 04 '12 at 17:19
  • @TedHopp I'm doing the wrong math ... I could compare both vectors, but I just thought using `Set` would be the smarter way – cybertextron Nov 04 '12 at 17:19
  • @Bohemian No. `""` is a property common between two `Strings`. They do have a `String` in common. – cybertextron Nov 04 '12 at 17:20
  • @philippe - If you count the empty string as a prefix and suffix, then the results should be (by my hand calculation): 1, 8, 1. – Ted Hopp Nov 04 '12 at 17:21
  • @TedHopp I changed my code .. could you run it and verify the results? – cybertextron Nov 04 '12 at 17:23
  • You are asking for the number of characters that are intersecting (not the intersection itself) I suppose, but I don't see either how you can get your result. – Maarten Bodewes Nov 04 '12 at 17:23
  • @owlstead I should return the intersection between the two vectors. `abbabba` has 4 candidates in common, while `codility` has 0. Just do a `System.out.println()` to see all the candidates generated. – cybertextron Nov 04 '12 at 17:26
  • Your results make no sense. If you count the empty string, *every* string has at least one, because the empty string would then be a prefix and suffix for any string. And do you *have* to use `Vector`s and `Set`s? There are other ways to solve your problem that are both easier and waste less memory. – NullUserException Nov 04 '12 at 17:28
  • Oops. I was wrong about palindromes. For "abbabba" the prefixes are "a", "ab", "abb", "abba", "abbab", "abbabb", and "abbabba". The suffixes are "a", "ba", "bba", "abba", "babba", "bbabba", and "abbabba". The intersection is "a", "abba", and "abbabba". Shouldn't the correct answer thus be 3? Note that your `getSuffix` method collects the **reverse** of the suffixes. – Ted Hopp Nov 04 '12 at 17:30
  • @TedHopp You're correct. This problem is just a set property. The answer is the intersection between the two sets. – cybertextron Nov 04 '12 at 17:33
  • @NullUserException. It's just the answer I found for the problem ... I'm definitely open for a better working solution – cybertextron Nov 04 '12 at 17:34

4 Answers4

2

I'd write your method as follows:

public int max_prefix_suffix(String s) {
    final int len = s.length();
    if (len == 0) {
        return 1; // there's some dispute about this in the comments to your post
    }
    int count = 0;
    for (int i = 1; i <= len; ++i) {
        final String prefix = s.substring(0, i);
        final String suffix = s.substring(len - i, len);
        if (prefix.equals(suffix)) {
            ++count;
        }
    }
    return count;
}

If you need to compare the prefix to the reverse of the suffix, I'd do it like this:

final String suffix = new StringBuilder(s.substring(len - i, len))
    .reverse().toString();
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • it returns `1, 7, 0` instead of `1, 4, 0` – cybertextron Nov 04 '12 at 17:40
  • if not 4 then 3, i.e. "a", "abba", and "abbabba" – Arham Nov 04 '12 at 17:43
  • @Arham you're right ... 3 is correct, however the answer returns `1, 3, 1` – cybertextron Nov 04 '12 at 17:44
  • @Arham - If OP wants to compare the prefix to the reverse of the suffix (as his original code does), then the answer should be 7. Otherwise, the answer should be 3. (It's only 4 if OP also always wants to include the empty string as a prefix/suffix, but then the last number should be 1, not 0.) – Ted Hopp Nov 04 '12 at 17:44
  • @philippe http://ideone.com/ELuT82 ; the entire string is both a prefix and a suffix, so you've got at least one match there. You *could* exclude it, then you'd only have *proper* suffixes and prefixes. See: http://en.wikipedia.org/wiki/Substring#Prefix – NullUserException Nov 04 '12 at 17:45
  • @philippe So basically there are two edge cases to consider: the whole string being a prefix/suffix, and whether or not the empty string is a prefix/suffix. Depending on these, you could have one or zero matches for the empty string, and at least one or two matches for any non-empty string. I would ask your professor for clarification. If that's not an option, document whatever you do. – NullUserException Nov 04 '12 at 17:52
  • @philippe it gives 1 for codility because at the end of the loop, both prefix and suffix are same. If you remove that then the answer would be, 1,2,0....I guess you first need to define what is intersection as per you. – Arham Nov 04 '12 at 17:53
0

I see that the code by @ted Hop is good.. The question specify to return the max number of matching characters in Suffix and Prefix of a given String, which is a proper subset. Hence the entire string is not taken into consideration for this max number.

Ex. "abbabba", prefix and suffix can have abba(first 4 char) - abba (last 4 char),, hence the length 4 codility,, prefix(c, co,cod,codi,co...),, sufix (y, ty, ity, lity....), none of them are same. hence length here is 0.

By modifying the count here from

if (prefix.equals(suffix)) {
    ++count;
}

with

if (prefix.equals(suffix)) {
    count = prefix.length();// or suffix.length()
}

we get the max length. But could this be done in O(n).. The inbuilt function of string equals, i believe would take O(n), and hence overall complexity is made O(n2).....

A.H.
  • 63,967
  • 15
  • 92
  • 126
ravi.zombie
  • 1,482
  • 1
  • 20
  • 23
0

i would use this code.

public static int max_prefix_suffix(String S)
{
    if (S == null)
        return -1;
    Set<String> set = new HashSet<String>();
    int len = S.length();
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < len - 1; i++)
    {
        builder.append(S.charAt(i));
        set.add(builder.toString());
    }
    int max = 0;
    for (int i = 1; i < len; i++)
    {
        String suffix = S.substring(i, len);
        if (set.contains(suffix))
        {
            int suffLen = suffix.length();
            if (suffLen > max)
                max = suffLen;
        }
    }
    return max;
}
string.Empty
  • 10,393
  • 4
  • 39
  • 67
0

@ravi.zombie If you need the length in O(n) then you just need to change Ted's code as below:

int max =0;
for (int i = 1; i <= len-1; ++i) {
    final String prefix = s.substring(0, i);
    final String suffix = s.substring(len - i, len);
    if (prefix.equals(suffix) && max < i) {
        max =i;
}
    return max;
}

I also left out the entire string comparison to get proper prefix and suffixes so this should return 4 and not 7 for an input string abbabba.

Satadru
  • 13
  • 3