我正在尝试查找非常大的字符串的子字符串并导致内存错误:
代码:
def substr(string):
le = []
st = list(string)
for s in xrange(len(string)+1):
for s1 in xrange(len(string)+1):
le.append(''.join(st[s:s1]))
cou = Counter(le)
cou_val = cou.keys()
cou_val.remove('')
return le, cou_val
我收到错误,因为ile" solution.py",第31行,在substr le.append(''。加入(ST [S:S1])) 的MemoryError
如何解决这个问题?
答案 0 :(得分:1)
<强>答案强>
我注意到您的代码按特定顺序打印了字符串的所有可能子字符串。我建议不要将所有这些存储在数组中,而是使用代码返回所需的子字符串。我用'非常长的字符串'测试了下面的子程序,并且它总是返回相同的值,就像从数组中获取索引值一样。
string = 'a very long string'
def substr2(string,i):
return string[i//(len(string)+1):i%(len(string)+1)]
print(substr2(string,10))
<强>解决方案强>
为for循环(s,s1)命令参数的方式与数字系统的工作方式类似。 s1递增1直到达到给定值,然后它重置为0并且s递增1,重复循环。这可以用十进制表示(例如01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16等)。
i // n div运算符返回i / n的整数值。 (例如14 // 10 = 1)。 i%n mod运算符返回i / n的余数值。 (例如14%10是4)。
因此,如果我们将i增加1并将(s,s1)定义为[i // 10,i%10],我们将得到:
[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7] ,[0,8],[0,9],[1,0],[1,1],[1,2]等。
我们可以利用这些来产生与数组相同的答案。
PS。我的第一个答案。希望这有帮助!
答案 1 :(得分:0)
你的内存似乎已经不多了。当string
太大时,您发布的代码似乎将其一遍又一遍地复制到le
列表中。正如@ Rikka的链接所示,buffer/memoryview可能对您有用,但我从未使用它。
作为解决方案/代码的变通方法,我建议不要将每个子字符串存储在le
中,而是将索引存储为元组。另外,我不认为st
列表是必需的(不确定如果你的方式加快它)所以结果将是(代码未测试):
def substr(string):
le = []
for s in xrange(len(string)+1):
for s1 in xrange(len(string)+1):
# Skip empty strings
if s!=s1:
le.append((s, s1))
cou = Counter(le)
cou_val = cou.keys()
cou_val.remove('')
return le, cou_val
现在,您可以使用substr
的示例是(代码未经过测试):
myString = "very long string here"
matchString = "here"
matchPos = False
indexes, count = substr(myString)
# Get all the substrings without storing them simultaneously in memory
for i in indexes:
# construct substring and compare
if myString[i[0],i[1]]==matchString:
matchPos = i
break
在上面之后,您将第一次出现的“here”的开始和结束位置放入您的大字符串中。我不确定你试图实现什么,但是可以很容易地修改它以查找所有出现次数,计数匹配等 - 我只是将其作为示例发布。我也不确定为什么Counter
在那里......
这种方法不应该出现内存错误,但是,它是内存和CPU之间的权衡,我希望它在运行时有点慢,因为每次使用indexes
时都必须重新构建每个子串。
希望有所帮助
答案 2 :(得分:-1)
解决方案:
内存中的错误总是由超出范围引起。切片技术也有一些规则。
当步骤为正时,就像1一样,第一个索引必须大于第二个。而相反,当为负数时,如-1,索引的数量比第二个短,但实际上更大一个。( - 1> -2)
所以在你的程序中,当step为1时,索引s
大于s1
,所以你访问了一个你没有申请它的地方。你知道,那是MemoryError
!! !