3

各要素がX要素の配列である多次元配列が必要です-3としましょう。

基本的に、3 番目の要素で 0 から y (12 としましょう) までカウントしたいのですが、0,0,12 の後、配列の次の要素を配列 0,1,0 にします - 12,12 で終了します。 12.

base...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 つが必要になることもあります。

再帰が答えだと確信していますが、この特定の問題について頭を曲げることができないようです。

10 秒ではなく 12 秒でカウントアップするものがない限り?

すべてのアドバイスに感謝します。

4

3 に答える 3

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>";

ふぅ……問題文を読んで思った以上に疲れた脳みそには難しかった。これでうまくいくはずです...コードに関して質問がある場合は、お気軽にお問い合わせください。

私は今それをテストしました、そしてそれは期待されることをします。テスト中に愚かなエラーが発生しましたが、これは修正されています。遅れて申し訳ありません。

于 2013-03-20T16:53:46.703 に答える
2

このアルゴリズムは、合計で必要なループの数を事前に計算し、次に $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;
    }
}

これは私が見つけた最も洗練されたソリューションです。毎回必要な配列を取得するためにべき乗と係数を使用する 1 つの算術演算を含む 2 つのネストされたループのみです。

要素や基数を調整するだけです。

3 つの位置を持つ配列を計算するのに 0.014 秒かかりました。

4 つの位置を持つ配列を計算するのに 0.25 秒かかりました。

5 つの位置を持つ配列を計算するのに 4.08 秒かかりました*

* 5 つの位置については、memory_limit を増やす必要がありました。配列が大きくなりすぎたためだと思います。巨大な配列を格納する代わりに数値の出力だけを行うと、このスクリプトははるかに軽くなります。

于 2013-03-21T09:52:10.417 に答える
0

基本的な再帰は次のとおりです。

<?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-03-20T16:52:54.387 に答える