2012-07-01 23 views
18
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 

Los errores anteriores aparecieron cuando intenté ejecutar el siguiente programa. ¿Puede alguien explicar qué es un error de memoria y cómo superar este problema? . El programa toma cadenas como entrada y encuentra todas las cadenas secundarias posibles y crea un conjunto (en orden lexicográfico) y debe imprimir el valor en el índice respectivo solicitado por el usuario, de lo contrario debe imprimir 'No válido'error de memoria en python

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() 
+5

Usted está fuera de la memoria: http://docs.python.org/library/exceptions.html – usoban

+1

Creo que se está quedando sin memoria, ¿podría publicar sus datos de entrada? –

+0

¿Qué estás tratando de hacer? – robert

Respuesta

12

Ésta aquí:

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]) 

parece ser muy ineficiente y costoso para las grandes cadenas.

mejor hacer

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) 

Un objeto búfer mantiene una referencia a la cadena original y el inicio y los atributos de longitud. De esta forma, no se produce una duplicación innecesaria de datos.

Una serie de longitud l tiene l*l/2 subcadenas de longitud media l/2, por lo que el consumo de memoria sería más o menos ser l*l*l/4. Con un buffer, es mucho más pequeño.

Tenga en cuenta que buffer() solo existe en 2.x. 3.x tiene memoryview(), que se utiliza ligeramente diferente.

Aún mejor sería calcular los índices y cortar la subcadena a pedido.

5

A memory error significa que su programa se ha quedado sin memoria. Esto significa que su programa de alguna manera crea demasiados objetos.

En su ejemplo, debe buscar partes de su algoritmo que podrían estar consumiendo mucha memoria. Sospecho que su programa recibe cadenas muy largas como entradas. Por lo tanto, s[i:j+1] podría ser el culpable, ya que crea una nueva lista. La primera vez que lo usa, no es necesario porque no usa la lista creada. Se podría tratar de ver si la siguiente ayuda:

if j + 1 < a: 
    sub_strings.append(s[i:j+1]) 

Para volver a colocar la segunda creación de la lista, que sin duda debe utilizar un objeto buffer, según lo sugerido por glglgl.

También tenga en cuenta que, dado que se utiliza if j >= i:, no es necesario para iniciar su xrange a 0. Puede tener:

for i in xrange(0, a): 
    for j in xrange(i, a): 
     # No need for if j >= i 

Una alternativa más radical sería la de tratar de reelaborar su algoritmo para que no precomputa todas las posibles cadenas secundarias. En cambio, simplemente puede calcular la subcadena que se solicita.

+1

Ya sé que, un poco más de explicación sobre por qué esto está sucediendo en este caso sería más útil . –

+2

Simplemente estaba tratando de dar una respuesta clara al título de su pregunta, en caso de que alguien lo encuentre buscando 'MemoryError' y Python. – Rodrigue

+0

@kratos Usted lo pidió: "¿Alguien puede explicar qué es un error de memoria?" – glglgl

0

puede tratar de crear el mismo script que emerge ese error, dividiendo el script en varios scripts importando del script externo. Por ejemplo, hello.py espera un error Error de memoria, entonces divido hola.py en varios guiones h.py e.py ll.py o.py todos ellos tienen que entrar en una carpeta "hellohello" en esa carpeta crear init.py en init escribe importación h, e, ll, o y luego en ide, escribe importación hellohello

1

El uso de python de 64 bits resuelve muchos problemas.

+5

¿Sería útil para otros usuarios decir por qué soluciona los problemas? – DeadChex

7

Si obtiene un inesperado MemoryError y cree que debería tener suficiente RAM disponible, podría ser porque está utilizando una instalación de Python de 32 bits.

La solución fácil, si tiene un sistema operativo de 64 bits, es cambiar a una instalación de 64 bits de python.

El problema es que la python de 32 bits solo tiene acceso a ~ 4GB de RAM. Esto puede reducirse aún más si su sistema operativo es de 32 bits, debido a la sobrecarga del sistema operativo.

Usted puede aprender más acerca de por qué los sistemas operativos de 32 bits se limitan a ~ 4 GB de RAM aquí: https://superuser.com/questions/372881/is-there-a-technical-reason-why-32-bit-windows-is-limited-to-4gb-of-ram