I\'m trying to create a data structure that holds all the possible substring combinations that add up to the original string. For example, if the string is \"java\"
Just in case someone will look for the same algorithm in python, here is implementation in Python:
from itertools import combinations
def compositions(s):
n = len(s)
for k in range(n):
for c in combinations(range(1, n), k):
yield tuple(s[i:j] for i, j in zip((0,) + c, c + (n,)))
Example how it works:
>>> for x in compositions('abcd'):
... print(x)
('abcd',)
('a', 'bcd')
('ab', 'cd')
('abc', 'd')
('a', 'b', 'cd')
('a', 'bc', 'd')
('ab', 'c', 'd')
('a', 'b', 'c', 'd')
With a small modification you can generate compositions in different order:
def compositions(s):
n = len(s)
for k in range(n):
for c in itertools.combinations(range(n - 1, 0, -1), k):
yield tuple(s[i:j] for i, j in zip((0,) + c[::-1], c[::-1] + (n,)))
It will give you this:
>>> for x in compositions('abcd'):
... print(x)
('abcd',)
('abc', 'd')
('ab', 'cd')
('a', 'bcd')
('ab', 'c', 'd')
('a', 'bc', 'd')
('a', 'b', 'cd')
('a', 'b', 'c', 'd')
And with another small addition, you can generate only specified number of splits:
def compositions(s, r=None):
n = len(s)
r = range(n) if r is None else [r - 1]
for k in r:
for c in itertools.combinations(range(n - 1, 0, -1), k):
yield tuple(s[i:j] for i, j in zip((0,) + c[::-1], c[::-1] + (n,)))
>>> for x in compositions('abcd', 3):
... print(x)
('ab', 'c', 'd')
('a', 'bc', 'd')
('a', 'b', 'cd')