Determine if a sequence is an interleaving of a repetition of two strings

隐身守侯 提交于 2019-12-10 22:48:00

问题


I have this task:

Let x be a string over some finite and fixed alphabet (think English alphabet). Given an integer k we use x^k to denote the string obtained by concatenating k copies of x. If x is the string HELLO then x^3 is the string HELLOHELLOHELLO. A repetition of x is a prefix of x^k for some integer k. Thus HELL and HELLOHELL are both repetitions of HELLO. An interleaving of two strings x and y is any string that is obtained by shuffling a repetition of x with a repetition of y. For example HELwoLOHELLrldwOH is an interleaving of HELLO and world. Describe an algorithm that takes three strings x, y, z as input and decides whether z is an interleaving of x and y.

I've only come up with a solution, which has exponential complexity (We have pointer to the z word, and kind of a binary tree. In every node I have current states of possible words x and y (at the start both blank). I'm processing z, and nodes has one/two/no children depending on if the next character from z could be added to x word, y word or no word.) How could I get better than exponential complexity?


回答1:


Suppose the two words x and y have length N1 and N2.

Construct a non-deterministic finite state machine with states (n1, n2) where 0 <= n1 < N1 and 0 <= n2 < N2. All states are accepting.

Transitions are:

c: (n1, n2) --> ((n1 + 1) % N1, n2) if x[n1] == c
c: (n1, n2) --> (n1, (n1 + 1) % n2) if y[n2] == c

This NDFSM recognises strings that are formed from interleaving repetitions of x and y.

Here's some ways to implement the NDFSM: https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton#Implementation

Here's a simple Python implementation.

def is_interleaved(x, y, z):
    states = set([(0, 0)])
    for c in z:
        ns = set()
        for i1, i2 in states:
            if c == x[i1]:
                ns.add(((i1+1)%len(x), i2))
            if c == y[i2]:
                ns.add((i1, (i2+1)%len(y)))
        states = ns
    return bool(states)

print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOH')
print is_interleaved('HELLO', 'world', 'HELwoLOHELLrldwOHr')
print is_interleaved('aaab', 'aac', 'aaaabaacaab')

In the worst case, it'll run in O(N1 * N2 * len(z)) time and will use O(N1 * N2) space, but for many cases, the time complexity will better than this unless the strings x and y are repetitious.



来源:https://stackoverflow.com/questions/37243991/determine-if-a-sequence-is-an-interleaving-of-a-repetition-of-two-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!