3

すでに同様の質問をしましたが、別の効果が必要です。元の質問はここにあります。


単純な配列があります。配列の長さは常に平方数です。したがって、16、25、36など。

$array = array('1', '2', '3', '4' ... '25');

私がやっていることは、配列をHTMLで配置して、辺が偶数のブロックのように見えるようにすることです。

私がやりたいのは、要素を並べ替えることです。これにより、JSONでエンコードされた配列をjQueryに渡すと、配列が繰り返され、現在のブロックがフェードインするため、円形のアニメーションが得られます。だから私はこのような配列をソートしたいと思います

だから私のソートされた配列は次のようになります

$sorted = array('1', '6', '11'', '16', '21', '22', '23' .. '13');

そうする方法はありますか?..ありがとう


編集:

私はこれを使って行列のような列/行配列を作成することでこれを行おうとしています:

$side = 5;

$elems = $side*$side;
$array = range(1,$elems);

for($i=1; $i <= $side; $i++) {
   for($x=$i; $x <= $elems; $x=$x+$side) {
      $columns[$i][] = $x; 
   }
}

for($i=1, $y=1; $i <= $elems; $i=$i+$side, $y++) {
   for($x=$i; $x < $side+$i; $x++) {
      $rows[$y][] = $x;
   }
}

私の次のステップは、最初の列を下に移動し、最後に最後の要素の列に移動する場合、最後に最後の要素に移動するなどです。誰かがより良いアイデアを持っている場合は、それは素晴らしいことです:)

4

4 に答える 4

1

これは、グリッドが常に正方形である限り機能します。

<?php

    // The size of the grid - 5x5 in the example above
    $gridSize = 5;

    // Create a 2D array representing the grid
    $elements = array_chunk(range(1, pow($gridSize, 2)), $gridSize);

    // Find the half way point - this will be the end of the loop since we
    // want to stop in the middle
    $end = ceil($gridSize / 2);

    // An array to hold the result    
    $result = array();

    // The stopping point of the current interation
    $stop = $gridSize;

    // Loop from start to the middle
    for ($i = 0; $i < $end; $i++) {

        // start in the top left corner
        $x = $y = $i;

        // Traverse Y top to bottom
        while ($y < $stop) {
            $result[] = $elements[$y++][$x];
        }
        $y--;
        $x++;

        // Traverse X left to right
        while ($x < $stop) {
            $result[] = $elements[$y][$x++];
        }
        $x--;
        $y--;

        // Traverse Y bottom to top
        while ($y >= $gridSize - $stop) {
            $result[] = $elements[$y--][$x];
        }
        $y++;
        $x--;

        // Make sure we come in a level
        $stop--;

        // Traverse X right to left
        while ($x >= $gridSize - $stop) {
            $result[] = $elements[$y][$x--];
        }
    }

    print_r($result);

それが機能しているのを見る

于 2013-03-04T14:59:44.070 に答える
0

私の解決策:

トリックは: 最初の実行は 5 で、次に 4 要素の 2 つの実行、3 要素の 2 つ、2 要素の 2 つ、1 要素の 2 つです。(5,4,4,3,3,2,2,1,1) 各実行では、状態モジュール 4 がインクリメントされます。状態に応じて、実行は一方向または他の方向に進みます。

コードは次のとおりです。

function circularSort(array $array) {
    $n2=count($array);
    $n=sqrt($n2);
    if((int)$n != $n) throw new InvalidArgumentException();

    $Result = Array();
    $run =$n; $dir=1;
    $x=0; $y=-1;
    $i=0;
    $st=0;
    while ($run) {
        while ($dir) {
            for ($j=0; $j<$run; $j++) {

                if ($st==0) $y++;
                if ($st==1) $x++;
                if ($st==2) $y--;
                if ($st==3) $x--;

                $p=$y * $n +$x;
                array_push($Result,$array[$p]);

            }
            $st = ($st +1) & 3;
            $dir--;
        }

        $dir=2;
        $run--;
    } 

    return $Result;
}

$a = range(1,25);
var_dump(circularSort($a));
于 2013-03-06T16:58:42.917 に答える
0

これはうまくいくはずです。任意の配列をcircularSort関数に渡すことができ、ソートされた配列が返されます。

/*
Get the circular sorted array
*/
function circularSort($array)
{
    //Get the length of array
    $arrayLength = count($array);
    //Find the square root of length of array
    $arrayRows = sqrt($arrayLength);

    //Divide the arrays in $arrayRows
    $arrayChunks = array_chunk($array,$arrayRows);
    $circularArray = array();

    //Call Circular Array function .. Result will be stored in $circularArray
    circularArray($arrayChunks,$circularArray);
    return $circularArray;
}

/*
Loop arrayChunk in following order
1. Fetch first item from each chunks
2. Fetch all items from last chunk and remove that array from arrayChunk
3. Reverse elements in each remaining chunk
4. Reverse entire arrayChunk array
5. Repeat above 4 steps until $arrayChunks is empty
*/
function circularArray(&$arrayChunks, &$circularArray)
{
    if(empty($arrayChunks))
    {
        return true;
    }

    //1. Fetch first item from each chunks
    foreach($arrayChunks as &$arrayChunk)
    {
        $circularArray[] = array_shift($arrayChunk);
    }

    //Fetch Last Chunk from array
    $lastChunk = array_pop($arrayChunks);

    //2. Fetch all items from last chunk and remove that array from arrayChunk
    foreach($lastChunk as $chunkElement)
    {
        $circularArray[] = $chunkElement;
    }

    //3. Reverse elements in each remaining chunk
    foreach($arrayChunks as &$arrayChunk)
    {  
        if (is_array($arrayChunk))
        {    
            $arrayChunk = array_reverse($arrayChunk);
        }
    }

    $arrayChunks = array_reverse($arrayChunks);

    return circularArray(&$arrayChunks, &$circularArray);
}

例えば

$array = range(1, 25);
$circularArray = circularSort($array);
于 2013-03-04T15:08:41.510 に答える
0

O(n) の別のアプローチ:

<?php
function circ_sort ($inArray) {

    $rowSize = pow(count($inArray), 0.5);
    if((int)$rowSize != $rowSize) {
        throw new InvalidArgumentException();
    }
    $rowSize = (int)$rowSize;

    $round =-1;
    for ($x =-1, $y=0, $count =0; $count < count($inArray);) {

        if ($y > $x) {
            if ($x +1 == $y) {
                $direction = 'D';   //Down
                $round ++;
                $max_iter = $rowSize - (2 * $round);
            } else {
                $direction = 'L'; //Left
                $max_iter = $y - $x -1;
            }
        } else if ($x > $y) {
            $direction = 'R'; //Right
            $max_iter = $rowSize - (2 * $round) -1;

        } else if ($x == $y) {
            $direction = 'U'; //Up
            $max_iter = $rowSize - (2 * $round) -1;

        }

        switch ($direction) {
            case 'D':   //Down
                for ($iter =0; $iter < $max_iter; $iter++) {
                    $x++;
                    $circArray[] = $inArray[$x*$rowSize + $y];
                    $count++;
                }
                break;
            case 'R': //Right
                for ($iter =0; $iter < $max_iter; $iter++) {
                    $y++;
                    $circArray[] = $inArray[$x*$rowSize + $y];
                    $count++;
                }
                break;
            case 'U':   //Up
                for ($iter =0; $iter < $max_iter; $iter++) {
                    $x--;
                    $circArray[] = $inArray[$x*$rowSize + $y];
                    $count++;
                }
                break;
            case 'L':   //Left
                for ($iter =0; $iter < $max_iter; $iter++) {
                    $y--;
                    $circArray[] = $inArray[$x*$rowSize + $y];
                    $count++;
                }
                break;
        }
    }
    return ($circArray);
}

$array = range(1, 25);
$circ_array = circ_sort($array);

var_dump($circ_array);

?>
于 2013-03-04T17:45:03.993 に答える