Tengo este bloque de código.
$input = 4; $list_N = array('0', '1'); for($n=1; $n<=$input; $n++) { if($n%2 == 0) { $c++; } $reverse_list_N = array_reverse($list_N); $A = array(); $B = array(); for($i=0; $i<count($list_N); $i++) { $A[] = '0' . $list_N[$i]; $B[] = '1' . $reverse_list_N[$i]; } $list_N = array_merge($A[], $B[]); if($n == 1) { $list_N = array('0', '1'); } } $array_sliced = array_slice($list_N, -1*$input, $input); for($i=0; $i<count($array_sliced); $i++) { $output = implode("\n", $array_sliced); } echo "<pre>"; print_r($output); echo "</pre>";Lo que hace este código es generar los siguientes datos (a partir de (0,1)):
0,1 00, 01, 11, 10 000, 001, 011, 010, 110, 111, 101, 100 ....... and so on Cuando $input = 4; la salida es:
1010 1011 1001 1000 Y como puede ver, después de cada ciclo, los elementos en la matriz $list_N que la anterior. Y con este ritmo si $input = 25; entonces la matriz tendría 33554432 elementos, lo cual es muy grande. Y ese es el problema que no pude encontrar una solución. Cuando $input = 60 me sale este error
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes)en esta línea
$list_N = array_merge($A, $B);Incluso establecer el límite de memoria en 2G no lo resolvió. Entonces, ¿cómo optimizo mi código para igualar la memoria? O, ¿hay alguna otra solución?
Actualización: Los siguientes pasos se utilizan para generar los datos.
$list_N is an array $reverse_list is the reverse of $list_N 0 is appended in the beginning of every element in the $list_N array and stored in $A 1 is appended in the beginning of every element in the $reverse_list_N array and stored in $B Array $A and array $B are merged and is stored in $list_N. The main loop runs for $input number of times and the last $input number of elements are displayed from the final array.Solución :
¡Intente usar un SplFixedArray !
Sobre:
Un SplFixedArray es
alrededor del 37% de una "matriz" regular del mismo tamaño
y
La clase
SplFixedArrayproporciona las principales funcionalidades de matriz. La ventaja es que permite una implementación de matriz más rápida.
Ejemplo:
$startMemory = memory_get_usage(); $array = new SplFixedArray(100000); for ($i = 0; $i < 100000; ++$i) { $array[$i] = $i; } echo memory_get_usage() - $startMemory, ' bytes';Otras lecturas:
Lea más: http://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html
Solución más desordenada:
Otra solución que podría ayudar, que no recomiendo, es anular la capacidad de memoria predeterminada. Puedes hacer esto usando esto:
ini_set('memory_limit', '-1')Otras lecturas:
@tadman tenía razón. Esto requiere un enfoque diferente. Ejecuté los números, el tamaño de la matriz en la entrada 65, asumiendo que solo 1 byte por elemento de la matriz es de 32 exabytes (se requiere una cantidad increíble de memoria solo para ejecutar este script).
//suponemos que el usuario ingresará la entrada como un entero positivo válido> 1
fscanf(STDIN, "%d\n", $target); $base=["0","1"]; $root=["0","1"]; $newArr=$base; for($i=1;$i<7;$i++)//pre-initialize root array $newArr=genNextArray($newArr); //echo "-----------\n"; //print_r($root); //we're ready to display the output now based on the root array elements displayNBits($target); function displayNBits($target) { global $root; $arr=array(); for($i=0;$i<$target;$i++) { $elem=str_pad($root[$i],$target,"0",STR_PAD_LEFT); $elem[0]="1"; $arr[]=$elem; } $arr=array_reverse($arr); for($i=0;$i<count($arr);$i++) echo $arr[$i]."\n"; //print_r($arr); } function genNextArray($arr) { global $root; $newArr= array(count($arr)*2); $ni=0; //0 prefix (left to right sweep) for($i=0;$i<count($arr);$i++) { $newArr[$ni]="0".$arr[$i]; $ni++; } //1 prefix (right to left sweep) for($i=count($arr)-1;$i>=0;$i--) { $newArr[$ni]="1".$arr[$i]; $root[]=$newArr[$ni]; $ni++; } return $newArr; }