Where are the duplicates coming from?
The code is building substrings of t
twice: By looping over values of j
and by always choosing the empty prefix of s
on each recursion.
For each iteration of j
you will append t[:j]
and then append a recursive call that will start with i = 0
, thereby appending more characters of t
. So the same substring of characters from t
will be created both by the j
loop and by recursion. For example, "12ab" can be built by starting with "1" in the first level of recursion, or by starting with "12" in the first layer of recursion.
(The pattern of duplicates is more obvious with longer strings, say "abc" and "123".)
Fixing the original solution
Let's fix the original solution. We want to build each annexed substrings of t
either via the j
loop or via recursion. For fun, I'll show a solution for each.
First, let's keep the j
loop. This means that we need force each recursive call to g
to not start with a character of t
. But we also need the special-case first call to g
to generate strings that start with characters of t
. Here's a semi-hacky way to do it:
def g( s, t, z=0 ) :
if ( s == "" ) :
return [ t ]
elif ( t == "" ) :
return [ s ]
else :
res = []
for i in xrange( z, len(s) ) :
for j in xrange( 1, len(t) + 1 ) :
res.extend( [ s[:i] + t[:j] + x for x in g( s[i:], t[j:], 1) ])
res.append( s + t )
return res
Each call to g
will iterate over all strings with all prefixes of s
followed by all prefixes of t
, followed by recursion (which must start with s
). The first call to g
is a special case, so we explicitly allow the first call to allow t
as the first prefix.
Or we can let recursion build the substrings of t
.
def g( s, t, ) :
if ( s == "" ) :
return [ t ]
elif ( t == "" ) :
return [ s ]
else :
res = []
for i in xrange( len(s) ) :
res.extend( [ s[:i] + t[:1] + x for x in g( s[i:], t[1:] ) ] )
res.append( s + t )
return res
In this version, we choose all prefixes of s
, add a character from t
, then recurse. Since we count ""
as a prefix of s
, substrings of t
greater than 1 will be built.
As an aside, when the recursion works, you can use
for i in xrange( len(s) + 1) :
to eliminate the line
res.append( s + t )