最大公共字符串python_如何找到多个字符串的最长公共子串?

这是一个相对优化的天真算法。您首先将每个序列转换为其所有ngram的集合。然后求所有集合的交集,并在交集中找到最长的ngram。在from functools import partial, reduce

from itertools import chain

from typing import Iterator

def ngram(seq: str, n: int) -> Iterator[str]:

return (seq[i: i+n] for i in range(0, len(seq)-n+1))

def allngram(seq: str) -> set:

lengths = range(len(seq))

ngrams = map(partial(ngram, seq), lengths)

return set(chain.from_iterable(ngrams))

sequences = ["brownasdfoersjumps",

"foxsxzxasis12sa[[#brown",

"thissasbrownxc-34a@s;"]

seqs_ngrams = map(allngram, sequences)

intersection = reduce(set.intersection, seqs_ngrams)

longest = max(intersection, key=len) # -> brown

虽然这可能会让你通过短序列,但这种算法在长序列上效率极低。如果你的序列很长,你可以添加一个启发式来限制最大可能的ngram长度(即最长的公共子串)。对于这种启发式方法,一个明显的值可能是最短序列的长度。在

^{pr2}$

这可能仍然需要太长时间(或使您的机器内存不足),所以您可能需要阅读一些最佳算法(请参阅我在评论中留下的对您的问题的链接)。在

更新

计算每个ngram出现的字符串数from collections import Counter

sequences = ["brownasdfoersjumps",

"foxsxzxasis12sa[[#brown",

"thissasbrownxc-34a@s;"]

seqs_ngrams = map(allngram, sequences)

counts = Counter(chain.from_iterable(seqs_ngrams))

Counter是dict的子类,因此其实例具有类似的接口:print(counts)

Counter({'#': 1,

'#b': 1,

'#br': 1,

'#bro': 1,

'#brow': 1,

'#brown': 1,

'-': 1,

'-3': 1,

'-34': 1,

'-34a': 1,

'-34a@': 1,

'-34a@s': 1,

'-34a@s;': 1,

...

您可以过滤计数,使子字符串至少出现在n字符串中:{string: count for string, count in counts.items() if count >= n}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值