有一段代码使用了lambda表达式
def ComputeArray(text):
# text is ended with $
if text[-1] != "$":
text += "$"
sarray = sorted(range(len(text)), key = lambda i: text[i:])
print ", ".join([str(x) for x in sarray])
if __name__ == "__main__":
ComputeArray("AACGATAGCGGTAAACGATAGCGGTAGA$")
它正确地输出了想要的数组
28, 27, 12, 0, 13, 1, 14, 25, 6, 19, 4, 17, 2, 15, 8, 21, 26, 3, 16, 7, 20, 9, 22, 10, 23, 11, 24, 5, 18
如何改进线路
sarray = sorted(range(len(text)), key = lambda i: text[i:])
所以当增加文本长度时,我不会在 lambda 表达式上使用大量内存?
Traceback (most recent call last):
File "C:\Array.py", line 23, in <module>
ComputeArray(text)
File "C:\Array.py", line 11, in ComputeArray
sarray = sorted(range(len(text)), key = lambda i: text[i:])
File "C:\Array.py", line 11, in <lambda>
sarray = sorted(range(len(text)), key = lambda i: text[i:])
MemoryError
更新
还有其他代码如:
sarray=[]
for i in range(len(text)):
sarray.append(text[i:])
order=[i[0] for i in sorted(enumerate(sarray), key=lambda x:x[1])]
print ", ".join([str(x) for x in order])
但是占用了这么多内存,
我还尝试使用 https://code.google.com/p/pysuffix/ 上可用的库解决方案
s = 'AACGATAGCGGTAGA'
s = unicode(s,'utf-8','replace')
n = len(s)
sa = tks.simple_kark_sort(s)
lcp = tks.LCP(s,sa)
print n print sa
虽然它解决了问题,但对于较大的字符串会花费太多时间,...您知道其他库或改进后缀的方法吗?
请您参考如下方法:
看起来您正在尝试构建后缀数组。幸运的是,这个算法已经有了 Python 实现:https://code.google.com/p/pysuffix/
如果你必须自己实现它,想想你的代码在做什么:
- 使用
range创建一个与文本长度相同的整数列表。 - 将
key函数应用于列表的每个元素并将结果存储在新列表中。 - 对新列表进行排序
- 返回与新列表的每个元素关联的原始整数。
(这也称为 Schwartzian Transform ,这是一个非常巧妙的想法。)
重点是,您正在为文本中的每个偏移量 制作一段(可能很大的)文本,并将其存储在新列表中。您需要使用更专业的后缀数组构造算法来避免此成本。
最后,解决您最初的问题:lambda 表达式不是这里的罪魁祸首。您只是遇到了算法墙。
EDIT
Here's a good resource for fast SA algorithms: What's the current state-of-the-art suffix array construction algorithm?
