我已经问了一个类似的问题,但我需要一个不同的效果。最初的问题是here。
我有一个简单的数组。数组长度始终是平方数。所以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;
}
}
我的下一步是走到第一列,如果它在最后一个元素列上,最后在最后一个元素上等,最后一行。如果有人有更好的想法,那将是伟大的:)
答案 0 :(得分: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);
答案 1 :(得分: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);
}
e.g。
$array = range(1, 25);
$circularArray = circularSort($array);
答案 2 :(得分: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);
?>
答案 3 :(得分:0)
我的解决方案:
诀窍是:第一次运行是5次,然后是4次运行的两次运行,3个元素中的两个,2个元素中的2个元素和1个元素中的两个元素。 (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));