有关字符串子串的顺序统计信息

时间:2012-02-25 00:27:58

标签: python algorithm memory

我有一个大小为s的长字符n和一个整数i。我对词典顺序下i的{​​{1}}子字符串感兴趣。

天真的方法是创建s的所有子串的集合,然后获得该集合的s阶统计量。这种方法需要i时间,但是构造O(n^2)的所有子串的集合太过密集了。

是否有更“记忆友好”的方法?

2 个答案:

答案 0 :(得分:3)

子字符串是字符串后缀的前缀。您可以使用http://en.wikipedia.org/wiki/Suffix_array中提到的算法之一,在时间O(n)中获得后缀的排序列表。 JuhaKärkkäinen和Peter Sanders(2003)提到的那个。 “简单的线性工作后缀阵列结构相当简单。

从排序的后缀列表中,某种延迟合并方案应该为您提供后缀的前缀的排序列表=排序的子串列表。

答案 1 :(得分:1)

这是获取第i个字符串的起始字符的方法:

s = "robert"

cumulative = 0
for c,num in sorted((j,i+1) for i,j in enumerate(reversed(s))):
    print c,num,cumulative
    cumulative+=x

b 4 0
e 3 4
o 5 7
r 2 12
r 6 14
t 1 20

现在从上面的结果(可以快速生成)中,您可以从累积值中看出,如果i介于0和4之间,我们应该使用'b'作为第一个字符。 如果我在7到12之间,我们会使用'o'作为第一个字符,依此类推。

为了验证这一点,我们可以查看有序的子字符串(参见7到12之间,它们都以'o'开头)(从索引0开始,包括7,不包括12):

print sorted([s[a:b] for a in range(n+1) for b in range(a+1,n+2)])
['b', 'be', 'ber', 'bert', 'e', 'er', 'ert', 'o', 'ob', 'obe', 'ober', 'obert', 'r', 'r', 'ro', 'rob', 'robe', 'rober', 'robert', 'rt', 't']

现在您可以使用此技术获取第一个字符。获得第一个字符后,您可以从累计值中了解您已经过了多少个子字符串。我们可以从i中减去这个累积值。现在我们来看一个新的字符串,它来自第一个(之前选择的)字符(不包括第一个字符)。我们再次应用相同的技术(使用新字符串和新的i值)来获得第二个字符。

希望这是有道理的。祝你好运。