【问题标题】:repeatedly remove occurrences of substring until main string is empty [duplicate]反复删除出现的子字符串,直到主字符串为空[重复]
【发布时间】:2023-03-31 22:27:01
【问题描述】:

所以我有堆栈和针:

stack = 'lllolollololollllolol'

needle = 'lol'

如果我每次都从stack 中删除一个needle,并且顺序正确,则stack 可以被清除,所以最后它是空的。 例如,每次删除粗体的lol(注意删除后可以进一步创建另一个needle):

lllolollolololllllolol

llolollolololl哈哈

大声笑大声笑大声笑

lollolololl

lollolol

l哈哈ol

哈哈

清除

要找到像上面这样的路线,我想出使用 Python 的唯一方法是使用正则表达式(finditer)在stack 中找到所有needles,并使用递归来探索所有可能的删除组合以找到可以使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.

【问题讨论】:

  • 由于 SO 不是一个代码编写服务,如果你想让它成为一个好问题,请添加你的代码。
  • 哈哈,是的,如果我看到这样的问题,我可能会说同样的话。我确实写了我的代码。这是我的 foo.bar 挑战解决方案的一部分(已提交)。我没有发布代码,因为我不确定是否应该发布代码。但我会用基本部分更新我的问题。

标签: python regex string algorithm substring


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    你可以递归:

    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的长度上具有指数时间复杂度。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 2 票不予置评??
      • 这将只替换第一次出现,它可能会或可能不会给您正确的结果。请参阅回溯算法。
      • 例如,它不适用于此示例:stack= 'lololl', needle='lol'
      猜你喜欢
      • 2021-01-23
      • 2018-04-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多