【问题标题】:Array with variable number of elements, counting up具有可变数量元素的数组,向上计数
【发布时间】:2013-03-09 20:36:30
【问题描述】:

我想要一个多维数组,其中每个元素都是 X 元素的数组 - 比如说 3。

我基本上想在第三个元素中从 0 计数到 y(比如说 12),然后在 0,0,12 之后我希望数组中的下一个元素是数组 0,1,0 - 以 12 结束,12,12.

我在以 ...12 为底数进行计数,当它完成时,会跳到数组中的下一个元素。

例如

0,0,0
0,0,1
...
0,0,12
0,1,0
0,1,1
0,1,2
...
0,1,12
0,2,0
...
12,12,12

好的,很好 - 我可以这样做

$maxCountNumber= 12;
$i=1;
for ($j=0; $j < $maxCountNumber+1; $j++) { 
    for ($k=0; $k < $maxCountNumber+1; $k++) { 
        for ($l=0; $l < $maxCountNumber+1; $l++) { 
                print "<br/>$i: $j, $k, $l";
                $results[$i] = array($j, $k, $l);
                $i++;
        }
    }
}

但是,如果我不想每次都只需要 3 个元素 - 有时我需要 4 个 - 而不是数百、十和单位,我想要千、百、十和单位……或者 7 个元素怎么样?

我确信递归是答案,但我似乎无法解决这个特定问题。

除非有什么事情可以在 12 秒而不是 10 秒内完成?

感谢您的所有建议。

【问题讨论】:

  • 模数通常用于这样的事情。你也看过 base_convert 吗?
  • 请注意,您的实现实际上是 base 13;你从 0 数到 12,包括 13 个数字。另外,您只是想数数还是希望在任意循环中的每个点都做某事?
  • 是的,会有更多 - 我想创建一个数组,其中数组中的所有元素加起来就是我要达到的总数 - 所以当 array[1] + array[2] + array[3] = 12,放入结果数组。
  • 嘿 AmyKate...我想我现在为你准备了一些东西。你肯定知道如何挑选问题……解决方案有点简单,但很难弄清楚……至少对我来说是这样。
  • 大家好,我知道了! :D 和@NathanielFord 它确实以 13 为底。我为我的解决方案感到非常自豪,至少与其他解决方案相比,并且考虑到我不太擅长数学。 (虽然我是亚洲人 xD)

标签: php recursion multidimensional-array


【解决方案1】:

该算法预先计算出总共需要的循环次数,然后使用 $i 计算每个数组位置的值。

$max= 13;
$elements = 4;
$loops = pow($max, $elements);

$main_array = array();

for($i = 0; $i < $loops; $i++){
    for($j = 0; $j < $elements; $j++){
        $main_array[$i][$j] = floor($i/pow($max,$elements-1-$j))%$max;
    }
}

这是我找到的最优雅的解决方案,只有 2 个嵌套循环和 1 个算术运算,每次使用幂和模数来获得所需的数组。

您只需调整元素和/或基数。

用 0.014 秒计算出 3 个位置的数组。

用 0.25s 计算出 4 个位置的数组。

用 4.08s 计算出 5 个位置的数组*

*对于 5 个位置,我需要增加 memory_limit,我猜是因为数组变得太大,如果你只输出数字而不是存储一个巨大的数组,这个脚本会轻得多。

【讨论】:

  • 啊!我知道了。我想我对所需数组的制定还不清楚;外部哈希数组包含位置,而不是实际值。为此和预先计算 +1。
  • 我实际上是靠运气偶然发现了这个解决方案,我的初始代码完全不同,然后突然我尝试预先计算所有可能性,一切都自动组合在一起 xD
【解决方案2】:

好吧,让我们看看...

$numberOfDimensions = 3;
$base = 13;

$YourArray = array();    //This array will hold the complete data.
$LastArray = array();
for($o = 0; $o < $numberOfDimensions; ++$o) //Gives us something to start with.
    $LastArray[$o] = 0;    

while($LastArray[0] < $base) {      //Makes sure, we're not going out of bounds
    $index = $numberOfDimensions - 1;
    $YourArray[] = $LastArray;      //Adds the array you filled last to the result array.
    while($index >= 0) {            //This is where things start to get interesting.
        if(++$LastArray[$index] < $base) break;  //Still in bounds, continue.
        else {
            if($index)              //Overflow for all but the first element..
                $LastArray[$index] = 0;
            --$index;               //Moving on to the previous digit.
        }
    }
}

echo "<pre>";
echo print_r($YourArray);
echo "</pre>";

呸……这对我疲惫的大脑来说比我读到这个问题时想象的要困难得多。这应该可行...如果您对代码有任何疑问,请随时提出。

我现在已经对其进行了测试,它可以达到预期的效果。在我的测试中,我遇到了一个愚蠢的错误,特此修复。抱歉耽搁了。

【讨论】:

    【解决方案3】:

    你的基本递归如下:

    <?php 
    class StrangeBase { 
      private static function loopOnStrangeBase($place, $base, $printstr) { 
        if (($place < 0) || ($base < 0)){ return; }//edge case 
        for ($idx=0; $idx<$base; $idx++) { 
          if ($place == 0) { 
            echo "$printstr,$idx\n"; 
          } else {
            if($printStr !== ''){ 
              StrangeBase::loopOnStrangeBase($place - 1, $base, $printstr.",$idx");
            } else {
              StrangeBase::loopOnStrangeBase($place - 1, $base, "$idx");
            }
          }
        } 
      }
    
      public static function printStrangeBase($places, $base) {
        StrangeBase::loopOnStrangeBase($places, $base, "");
      }
    } 
    
    StrangeBase::printStrangeBase(3, 12); 
    

    现在,您可以将其修改为不是静态函数,而是保存到一个数组中。为此,您的阵列应该“向后”增长;也就是说,数组中的第一个元素是您数字中的最低位。然后,您可以进一步修改递归函数以获取函数指针并运行任意代码,而不是简单地打印出它的位置。

    【讨论】:

      猜你喜欢
      • 2013-08-26
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      相关资源
      最近更新 更多