反复删除子字符串的出现,直到主字符串为空

时间:2015-07-06 20:10:45

标签: python regex string algorithm substring

所以我有堆叠和针头:

stack = 'lllolollololollllolol'

needle = 'lol'

如果我每次都从needle删除一个stack,并且使用正确的顺序,stack可以被清除,因此它在结尾处为空。 例如,每次都删除以粗体显示的lol(请注意,删除后可以进一步创建另一个needle):

lllolollolololll的洛尔

lllolollolololl的洛尔

lllolol的洛尔 ololl

llollolo的洛尔

llol的洛尔

1的洛尔

洛尔

明确

要找到上面这样的路由,我想出使用Python的唯一方法是使用正则表达式(finditer)查找needles中的所有stack,并使用递归来探索所有可能删除组合以找到可能使stack为空的组合。但我知道这根本没有效率。

是否有更有效的方法可以使用Python找到至少一种方法删除needle以清空stack

我找到了这个话题: Remove occurences of substring recursively 但我不确定它是否100%适用于我的情况。

谢谢!

以下是我提出的代码(我知道的复杂性很差......):

def answer(chunk, word):
    if chunk.find(word) != -1:
        occ = [m.start() for m in finditer('(?='+word+')', chunk)]
        for o in occ:
            new = chunk[:o] + chunk[o + len(word):]
            answer(new, word)
    else:
        result.append(chunk)
        result.sort()
        return chunk
...
#So all the shortest "leftover stack" after the removal are stored in list 
#"result". These include empty or non-empty outputs depending on how 
#the removal was executed.

3 个答案:

答案 0 :(得分:3)

作为解决此类任务的更通用方法,您可以使用Backtracking算法。

您可以从查找所有needle开始,然后在它们之间进行选择,然后删除将在下一个状态中遇到关键状态的选项。并继续检查其他needle s 。

答案 1 :(得分:3)

你可以递归:

import re

def find_all(bigstr, smallstr):
    return [m.start() for m in re.finditer(smallstr, bigstr)]

def removeNeedle(stack, needle, prev):
    if len(stack) == 0:
        print prev
    indices = find_all(stack, needle)
    for index in indices:
        newStack = stack[:index] + stack[index+3:]
        newPrev = list(prev)
        newPrev.append(index)
        removeNeedle(newStack, needle, newPrev)

stack = 'lllolollololollllolol'
needle = 'lol'

removeNeedle(stack, needle, [])

这将找到所有这样的可能解决方案。一些可能的结果如下:

[2, 1, 5, 1, 0, 1, 0]
[2, 1, 5, 1, 4, 0, 0]
[2, 1, 5, 1, 4, 3, 0]
[2, 1, 5, 7, 1, 0, 0]
[2, 1, 5, 7, 1, 3, 0]
[2, 1, 5, 7, 6, 1, 0]
[2, 1, 10, 5, 1, 0, 0]
[2, 1, 10, 5, 1, 3, 0]
[2, 1, 10, 5, 6, 1, 0]
[2, 1, 10, 9, 5, 1, 0]
[2, 4, 5, 1, 0, 1, 0]
[2, 4, 5, 1, 4, 0, 0]
[2, 4, 5, 1, 4, 3, 0]
[2, 4, 5, 7, 1, 0, 0]
[2, 4, 5, 7, 1, 3, 0]
[2, 4, 5, 7, 6, 1, 0]

您可以使用以下方式将其可视化:

def visualize(stack, prev):
    for p in prev:
        print stack
        print ' ' * p + '---'
        stack = stack[:p] + stack[p+3:]

visualize(stack, [2, 1, 5, 1, 0, 1, 0]) # one of the results

给你:

lllolollololollllolol
  ---
llollololollllolol
 ---
llololollllolol
     ---
llololllolol
 ---
lolllolol
---
llolol
 ---
lol
---

PS:此方法在stack的长度上具有指数时间复杂度。

答案 2 :(得分:-2)

您可以使用循环删除子字符串

stack = 'lllolollololollllolol'
needle = 'lol'

while needle in stack:
    stack = stack.replace(needle, '')

print stack