在另一个字符串中查找一个字符串的所有排列

时间:2021-04-27 19:08:11

标签: python algorithm dynamic-programming

我有一个字符串,例如:string1 = 'abcdbcabdcabb'。 我还有另一个字符串,例如:string2 = 'cab'

我需要计算 string2string1 的所有排列。

目前我正在将 string2 的所有排列添加到列表中, 然后通过 index+string.size 迭代抛出 string1 并检查 如果 string1 的子串包含在排列列表中

我相信有更好的优化方法可以做到这一点。

4 个答案:

答案 0 :(得分:4)

在我看来,您不需要 DP,而是需要滑动窗口技术。 string2 的排列是长度完全相同且字符分布相同的字符串。在您的 string2 示例中,排列是。具有以下字符分布的长度为 3 的字符串:{a:1,b:1,c:1}。

所以你可以写一个脚本,从string1(index=0)的开始,考虑一个大小为N(string2的大小)的窗口。如果您当前的窗口具有完全相同的字符分布,则接受它作为排列,否则不计算它,然后继续索引+1。

一个不重新计算每个滑动窗口中字符分布的技巧,你可以得到一个字符字典,并在第一个窗口计算字符,然后当你向右滑动窗口时,减少删除字符加一,加号加一。

代码应该是这样的,你需要验证它的边缘情况:

def get_permut(string1,string2):
    N =len(string2)
    M = len(string1)

    if M < N:
        return 0


    valid_dist = dict()
    for ch in string2:
        valid_dist.setdefault(ch,0)
        valid_dist[ch]+=1
    
    current_dist=dict()
    for ch in string1[:N]:
        current_dist.setdefault(ch,0)
        current_dist[ch]+=1
    
    ct=0
    for i in range(M-N):
        if current_dist == valid_dist:
            ct+=1
        current_dist[i]-=1
        current_dist.setdefault(i+1,0)
        current_dist[i+1]+=1
        if current_dist[i]==0:
            del current_dist[i]
    
    return ct
        

答案 1 :(得分:1)

您可以在这里使用 string.count() 方法。请参阅以下解决方法:

import itertools
perms=[''.join(i) for i in itertools.permutations(string2)]

res=0

for i in perms:
    res+= string1.count(i)

print(res)
# 4

答案 2 :(得分:0)

你可以使用正则表达式。

std::string{}

答案 3 :(得分:0)

这是一种使用正则表达式的愚蠢方法(实际上不要这样做)。

为搜索文本中的每个字母使用一个非捕获组,然后期望每个捕获组中的一个出现在输出中:

import re

string1 = 'abcdbcabdcabb'
string2 = r'(?:c()|a()|b()){3}\1\2\3'


pos = 0
r = re.compile(string2)
while m := r.search(string1, pos=pos):
    print(m.group())
    pos = m.start() + 1
abc
bca
cab
cab

也可以动态生成

import re

string1 = 'abcdbcabdcabb'
string2 = 'cab'

before = "|".join([f"{l}()" for l in string2])
matches = "".join([f"\\{i + 1}" for i in range(len(string2))])
r = re.compile(f"(?:{before}){{{len(string2)}}}{matches}")

pos = 0
while m := r.search(string1, pos=pos):
    print(m.group())
    pos = m.start() + 1
相关问题