子串发生的平均时间

时间:2016-03-02 12:29:32

标签: python algorithm

我有一个返回太多结果的程序,所以我想只采用高于平均值的有用结果。我的问题是字符串长度 N 是由 k 字母的字母表生成的,平均所有子串长度 m 的次数是多少次?例如在字符串" abcbbbbcbabcabcbcab"字母{a,b,c}平均长度3的所有子串发生了多少次,abc发生3次,bbb发生2次(即使它们重叠也算得上),依此类推。或者有没有办法在执行程序之前从python(我的代码所在的位置)知道它?

1 个答案:

答案 0 :(得分:0)

您想要计算特定字符串中的子字符串,还是想要一般情况下的理论平均值?在任何给定位置出现m字符长度为k的字符串的概率为1/(k^m),因此如果您的字符串长度为N个字符,那么预期的(N-m+1)/(k^m)-m+1出现次数,因为该字符串不能出现在最后m-1个位置)。另一种看待这种情况的方法是长度mN-m+1)的子串数除以不同的这种子串(k^m)的数量。

您可以计算示例的平均计数,以查看公式是否达到了正确的结果。当然,人们不应期待太多,因为它的样本量非常小......

>>> s = "abcbbbbcbabcabcbcab"
>>> N = len(s)
>>> k = 3
>>> m = 3

为此,公式给了我们

>>> (N-m+1)/(k**m)
0.6296296296296297

我们可以使用itertools.productcount函数来计算所有三个字母字符串的出现次数(str.count不会正确计算重叠的字符串):

>>> count = lambda x: sum(s[i:i+m] == x for i in range(len(s)))
>>> X = [''.join(cs) for cs in itertools.product("abc", repeat=3)]
>>> counts = [count(x) for x in X]

在这种情况下,这会为提供与公式相同的结果。 (我和你一样惊讶。)

>>> sum(counts)/len(counts)
0.6296296296296297