sln
sln

Reputation: 159

how to generate the shortest string from two string

I would like to write a function to return the shortest string C from two string, A, B and make sure string A, B is substring of C. But the key is length of A does not have to longer than B ex:

A: 'abcd', B: 'cde' = > C: 'abcde' # c,d is duplicated
A: 'abcd', B: 'ecd' = > C: 'abcdecd' #no character duplicated so C is A + B
A: 'abc', B: 'cdeab' = > C: 'cdeabc'
A: 'bce', B: 'eabc' = > C: 'eabce' #length of eabcd is 5, length of bceabc is 6
A: '', B: 'abc' = > C: 'abc'
A: 'abc', B: '' = > C: 'abc'

I have following function but it seems like it is not correct

def checksubstring(A, B):
    if not A or not B: return A if not B else B
    index, string = 0, ''
    for i, c in enumerate(A):
        index = index + 1 if c == B[index] else 0
        string += c
    return string + B[index:]

Upvotes: 9

Views: 187

Answers (2)

Manualmsdos
Manualmsdos

Reputation: 1547

You must check A,B and B,A, and after this check their results:

def checksubstring(A, B):
    if not A or not B: return A if not B else B
    index, string = 0, ''
    for i, c in enumerate(A):
        index = index + 1 if c == B[index] else 0
        string += c
    return string + B[index:]


def test(A, B):
    s1 = checksubstring(A, B)
    s2 = checksubstring(B, A)
    if len(s1) > len(s2):
        return s2
    else:
        return s1


print(test('abcd', 'cde'))  # = > C: 'abcde' # c,d is duplicated
print(test('abcd', 'ecd'))  #  = > C: 'abcdecd' #no character duplicated so C is A + B
print(test('abc', 'cdeab')) # = > C: 'cdeabc'
print(test('bce', 'eabc'))  # = > C: 'eabce' #length of eabcd is 5, length of bceabc is 6
print(test('', 'abc'))      # = > C: 'abc'
print(test('abc', ''))      # = > C: 'abc'

Upvotes: 0

Stephen Rauch
Stephen Rauch

Reputation: 49812

You can back up from the end looking for a match like:

Code:

def shortest_substring(a, b):

    def checksubstring(a, b):
        if not a or not b:
            return b or a

        for i in range(1, len(b)):
            if a[len(a) - i:] == b[:i]:
                return a + b[i:]
        return a + b

    x = checksubstring(a, b)
    y = checksubstring(b, a)
    return x if len(x) <= len(y) else y

Test Code:

results = [
    {'A': 'abcd', 'B': 'cde', 'C': 'abcde'},
    {'A': 'abcd', 'B': 'ecd', 'C': 'abcdecd'},
    {'A': 'abc', 'B': 'cdeab', 'C': 'cdeabc'},
    {'A': 'bce', 'B': 'eabc', 'C': 'eabce'},
    {'A': '', 'B': 'abc', 'C': 'abc'},
    {'A': 'abc', 'B': '', 'C': 'abc'},
]

for result in results:
    assert result['C'] == shortest_substring(result['A'], result['B'])

Upvotes: 6

Related Questions