Traceback (most recent call last): File "/run-1341144766-1067082874/solution.py", line 27, in main() File "/run-1341144766-1067082874/solution.py", line 11, in main if len(s[i:j+1]) > 0: MemoryError Error in sys.excepthook: Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 64, in apport_excepthook from apport.fileutils import likely_packaged, get_recent_crashes File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1, in from apport.report import Report MemoryError Original exception was: Traceback (most recent call last): File "/run-1341144766-1067082874/solution.py", line 27, in main() File "/run-1341144766-1067082874/solution.py", line 11, in main if len(s[i:j+1]) > 0: MemoryError
当我尝试运行以下程序时,出现了以上错误。有人可以解释什么是内存错误,以及如何解决此问题?。 该程序将字符串作为输入,并找到所有可能的子字符串,并从中创建一个集(按字典顺序),并应在用户要求的相应索引处打印值,否则应打印“无效”
def main(): no_str = int(raw_input()) sub_strings= [] for k in xrange(0,no_str): s = raw_input() a=len(s) for i in xrange(0, a): for j in xrange(0, a): if j >= i: if len(s[i:j+1]) > 0: sub_strings.append(s[i:j+1]) sub_strings = list(set(sub_strings)) sub_strings.sort() queries= int(raw_input()) resul = [] for i in xrange(0,queries): resul.append(int(raw_input())) for p in resul: try: print sub_strings[p-1] except IndexError: print 'INVALID' if __name__ == "__main__": main()
这一个在这里:
s = raw_input() a=len(s) for i in xrange(0, a): for j in xrange(0, a): if j >= i: if len(s[i:j+1]) > 0: sub_strings.append(s[i:j+1])
对于大型字符串,这似乎非常低效且昂贵。
做得更好
for i in xrange(0, a): for j in xrange(i, a): # ensures that j >= i, no test required part = buffer(s, i, j+1-i) # don't duplicate data if len(part) > 0: sub_Strings.append(part)
缓冲区对象保留对原始字符串以及开始和长度属性的引用。这样,不会发生不必要的数据重复。
长度的字符串l具有l*l/2平均长度的子串l/2,所以内存消耗将大致是l*l*l/4。使用缓冲区,它要小得多。
l
l*l/2
l/2
l*l*l/4
请注意,buffer()仅在2.x中存在。3.x具有memoryview(),其使用情况略有不同。
buffer()
memoryview()
更好的方法是计算索引并按需剪切子字符串。