PHP工作代码的奇怪问题

时间:2014-06-02 07:26:02

标签: php memory memory-management

有一种技术可以从(N)位代码生成(N + 1)位代码列表。

  1. 按给定顺序获取N位代码列表,并将其命名为List-N
  2. 反转上面的列表(List-N),并命名新的反映列表:Reflected-List-N
  3. 将原始列表(List-N)的每个成员前缀为0,并将此新列表命名为“A”
  4. 将新列表(Reflected-List-N)的每个成员前缀为1并将此新列表称为“B”
  5. 具有N + 1位的代码列表是列表A和B的串联。
  6. 以上步骤的演示:从2位神秘码生成3位神秘码列表

    1. 2位代码列表:00,01,11,10
    2. 反向/反映以上列表:10,11,01,00
    3. 前缀为0:000,001,011,010
    4. 的旧条目
    5. 前缀反射列表1:110,111,101,100
    6. 连接最后两个步骤中获得的列表:000,001,011,010,110,111,101,100
    7. 我找到了解决方案但是当我输入65例如获取错误时

      PHP Fatal error: Out of memory (allocated 538968064) (tried to allocate 20 bytes) in /home/pLR62k/prog.php on line 27

      在Ideone http://goo.gl/WB3DKh

      我做错了什么?

      <?php
      function MysteryCodes($input){
          $initArr=array(0,1);
          if($input==1){
              return $initArr;
          }
          else {
              $list=array();
              $list[0]=$initArr;
              for ($i=1; $i<$input; $i++)
                  {   
                      $prevIndex=$i-1;
                      $reflectedListN = array_reverse($list[$prevIndex]);
                      $listA=prefixR($list[$prevIndex], '0');
                      $listB=prefixR($reflectedListN, '1');
                      $list[$i]=array_merge($listA, $listB);
                  }
          }
          return array_slice($list[$input-1], -$input);
      }
      
      
      
      function prefixR($input, $prefix){
          $result=array();
          foreach($input as $value){
              $result[]=$prefix.$value;
          }
          return $result;
      }
      
      fscanf(STDIN, "%d", $inp);
      if($inp>=1 && $inp<=65){
      $result=MysteryCodes($inp);
      $output="";
      foreach($result as $key=>$value)
          $output.="$value\n";
      
      fwrite(STDOUT, $output);
      }   
      

3 个答案:

答案 0 :(得分:3)

你使用了太多的记忆。创建一个包含所有元素的数组只适用于小N

您在问题中说明&#34; 2-Bit Mystery Codes&#34; 都是四种可能的两位组合。然后,您的算法将成为生成所有可能N位组合的方法。对于N=65,组合的数量(以及您尝试存储的元素数量)是

2^65 = 36893488147419103232 ≈ 3 * 10^19

那很多。而且它甚至不计算你正在采取的所有中间步骤。假设没有开销,您的列表将占用大约30艾字节的内存。如果您想要生成这些数字,则必须将自己限制为较小的N,或者在不保存所有数据的情况下找到另一种计算它们的方法。

答案 1 :(得分:1)

function prefixR(&$input, $prefix){

应该已经对内存有很多帮助,因为数组被复制而不是通过引用传递

答案 2 :(得分:0)

你所做的几乎是正确的,除了&#34; array_merge&#34;。这将利用更多的内存。

下面的代码将像魅力一样工作!!!!

    $length = 100;//input value

    if($length > 1) {
        $mysteryArray = ['0', '1'];
        for ($i=2; $i <= $length; $i++) {
            $reverseArray = array_reverse($mysteryArray);

            $tempArray = [];

            foreach ($mysteryArray as $key => $value) {
                $tempArray[] = '0' . $value;
            }

            foreach ($reverseArray as $key => $value) {
                $tempArray[] = '1' . $value;
            }

            if($i != $length) {
                $mysteryArray = array_slice($tempArray, 0, $i+$length);
            } else {
                $mysteryArray = array_slice($tempArray, -$length, $length);
            }

        }
        foreach ($mysteryArray as $key => $value) {
            echo $value . '<br>';
        }
    } else {
        echo '1';
    }