我有一个字符串,例如:string1 = 'abcdbcabdcabb'
。
我还有另一个字符串,例如:string2 = 'cab'
我需要计算 string2
中 string1
的所有排列。
目前我正在将 string2
的所有排列添加到列表中,
然后通过 index+string.size
迭代抛出 string1 并检查
如果 string1
的子串包含在排列列表中
我相信有更好的优化方法可以做到这一点。
答案 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