3

I was given this:

Write a recursive program that, given a string with no spaces in it, breaks it into every possible segmentation of the string into "words". That is, print out every possible version of the string with spaces inserted in it. The order in which the segmented strings are given does not matter, but all possible segmentations must be given, with no repeats.

and at am a complete loss on how to even start, if someone could help.

The output is supposed to look like this:

 Enter a string: ABCD

 ABCD
 A BCD
 A B CD
 A B C D
 A BC D
 AB CD
 AB C D
 ABC D
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Brendan Lesniak
  • 2,271
  • 4
  • 24
  • 48
  • 3
    Take a look at http://stackoverflow.com/questions/717725/understanding-recursion. – Feanor Mar 11 '11 at 15:47
  • At first, do you know how recursion works? – Paŭlo Ebermann Mar 11 '11 at 15:48
  • No, I just want tips on how to start – Brendan Lesniak Mar 11 '11 at 15:48
  • Yes I know how recursion works, I have no clue how to get the correct substrings. – Brendan Lesniak Mar 11 '11 at 16:03
  • @Brendan that was not meant in a negative way! I really find it clever to get you help here. I was just depressed about why i didn't knew that platform the times i need to do programming homework :-) – Chris Mar 11 '11 at 16:23
  • @Chris, if you don't like programming on its own, it's a good idea to just ditch it in favor of something more enjoyable. – bestsss Mar 11 '11 at 16:57
  • @everyone, I am inclined to give 500 bounty to the shortest solution [in terms of semicolons] of the problem in java. The function would have signature like void `fillSpaces(String src, ArrayList target, int k)`. – bestsss Mar 11 '11 at 16:59
  • @bestsss - that would turn it into a copy & paste solution for any future homework hunters - whereas as it currently stands, it's giving hints (although reviewing my answer, I think I went too far) – Damien_The_Unbeliever Mar 11 '11 at 18:25
  • @Damien_The_Unbeliever, bounty can be added for a question old 2 days. Yet, the idea is to write the function with the least amount of semicolons (the solution will never pass for a homework, ever). – bestsss Mar 11 '11 at 18:37
  • Bestsss what would that solution be? (I bet it's something super clever) – Brendan Lesniak Mar 15 '11 at 19:11

5 Answers5

5

There's a pattern to the output you've been given (as in, in the order in which those outputs have been produced). Consider what outputs 2-5 have in common:

A BCD
A B CD
A B C D
A BC D

So, it looks like your function is going to print its input (ABCD), then it's going to take the first letter as a prefix (A), and recursively find all combinations of its remaining letters (BCD). This would hint that the actual definition for the function takes two parameters - a prefix that has already been expanded, and a set of remaining letters to enumerate the combinations for.

Having done that with one letter, we then move another letter across into this prefix (AB), and again recursively find all combinations for the remaining letters (CD), to produce the next set of outputs:

AB CD
AB C D
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
5

I will give you hints to help:

Think about how to solve this issue recursively. Basically, this could be solved with a variation of "divide and conquer". For a given string of length n, there are n-1 places where you can insert separator spaces.

Thus if you have a string of length 2, you have one place to insert a separator, and two variations: either you insert the separator, or not.

If you have a string of length 3, you have 2 choices in 2 places. Thus the function can create a string with the space inserted in the first place, and recursively call itself with the unprocessed tail of the string to produce all variations for that substring. Then create another prefix string where there is no space inserted in the first place, and again call itself with the rest of the string.

For each recursive call, it needs to pass itself the already generated prefix of the string, and the remaining unprocessed tail of the string.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
2

Thanks for being honest about this being homework. A trick for writing a recursive function Foo(n) is to assume that Foo(n-1) already works as it should. In this case, you are tasked with writing a function GenerateSpaceVariationsOfString(string s), which takes a string s as parameter and should return an array containing all possible variations of the string. (It will be easier to make a recursive function what returns its result rather than one that prints its results - then, you can just print the array you get from the function.) Let's say that s is of length n. Now, assume that you have a function that can take s minus its first letter and return an array of all possible space variations of that substring - in other words, assume that GenerateSpaceVariationsOfString(s.substring(1)) would give {"BCD", "BCD", "BC D", "BC D", ...} if s is ABCD. How could you use this to write GenerateSpaceVariationsOfString?

(In recursion, you also need a base case, so what should GenerateSpaceVariationsOfString(s) return if the length of s is 0 or 1?)

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
1

A simple recursive algorithm can be implemented if you realize that the segmentation of a string s is equal to a set containing s itself, and a set union of each substring X of s with the segmentation of s\X. Also, since you will always have n-1 possible substrings, and you can either segment or not segment in each of these points, you will always end up with 2^(n-1) segments.

It is more simple to understand with an example for the segmentation of the string ABC:

  1. {'ABC'} // 'ABC' itself
  2. {'A', 'B, 'C'} // substring 'A' union 1st segmentation of 'BC' = {'B, 'C'}
  3. {'A', 'BC'} // substring 'A' union 2nd segmentation of 'BC' = {'BC'}
  4. {'AB', 'C'} // substring 'AB' union 1st and only segmentation of 'C' = {'C'}
  5. Union of 1, 2, 3, and 4, yield all segmentations of the string ABC.

This translates almost directly to the following implementation:

public static Set<Set<String>> segment(String s) {
    // `s` itself.
    Set<Set<String>> result = new LinkedHashSet<Set<String>>();
    Set<String> root = new LinkedHashSet<String>();
    root.add(s);
    result.add(root);   

    // set union of each substring `X` (prefix) of `s` with `s\X` (rest).
    for (int i = 1; i < s.length(); i++) {   
        String prefix = s.substring(0, i);
        String rest = s.substring(i);
        for (Set<String> segments : segment(rest)) {
            Set<String> segment = new LinkedHashSet<String>();
            segment.add(prefix);
            segment.addAll(segments);
            result.add(segment);
        }
    }
    return result;
}

Sample outputs:

System.out.println(segment("ABC"));
// [[ABC], [AB, C], [A, B, C], [BC, A]]
System.out.println(segment("ABCD"));
// [[D, AB, C], [BCD, A], [D, ABC], [D, A, B, C], [AB, CD], [ABCD], [D, BC, A], [A, B, CD]]
João Silva
  • 89,303
  • 29
  • 152
  • 158
-1

Think of the joint between two letters as one bit. If the bit is 1, then you insert a space there, if it's 0, you don't. So if the string length is n, you create a bit sequence that's n-1 in length. Then you treat the bit sequence as an unsigned integer, and loop through all the possible values: 000, 001, 010 etc.

Of course, this isn't recursive, so you won't get credit for it.

Mike Baranczak
  • 8,291
  • 8
  • 47
  • 71