我有一个大小为s
的长字符n
和一个整数i
。我对词典顺序下i
的{{1}}子字符串感兴趣。
天真的方法是创建s
的所有子串的集合,然后获得该集合的s
阶统计量。这种方法需要i
时间,但是构造O(n^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值)来获得第二个字符。
希望这是有道理的。祝你好运。