これはあなたが求めるものに近いと思います: 配列内の項目の定数で、適度に均一な分布。
// The input array. 0s are regarded as blanks.
$array = array(1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
// Count the times each item occurs. PHP will probably have a function for that, but I don't know.
$counter = array();
foreach ($array as $item)
{
// Zeros are infill. Don't process them now, only process the other numbers and
// the zeros will occupy the remaining space.
if ($item === 0)
continue;
if (!array_key_exists($item, $counter))
$counter[$item] = 0;
$counter[$item]++;
}
// Reverse sort by quantity. This results in the best distribution.
arsort($counter);
// Pre-fill a new array with zeros.
$resultCount = count($array);
$result = array_fill(0, $resultCount, 0);
// Distribute the items in the array, depending on the number of times they occur.
foreach ($counter as $item => $count)
{
// Determine the division for this item, based on its count.
$step = $resultCount / $count;
// Add the item the right number of times.
for ($i = 0; $i < $count; $i++)
{
// Start with the index closest to the preferred one (based on the calculated step).
$index = 0;
$startIndex = (int)($step * $i);
// Count up until a right index is found.
for ($index = $startIndex; $index < $resultCount; $index++)
{
if ($result[$index] === 0)
{
$result[$index] = $item;
break;
}
}
// If no proper index was found, count fown from the starting index.
if ($index === $resultCount)
{
for ($index = $startIndex; $index >= 0; $index--)
{
if ($result[$index] === 0)
{
$result[$index] = $item;
break;
}
}
}
// Still no proper index found, that shouldn't be possible. There's always room.
if ($index === -1)
{
throw new Exception('This cannot not happen');
}
}
}
var_dump($result);
配列の場合:
1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
戻り値:
3,2,1,0,3,0,0,0,3,0,2,1,3,0,0,0,3,0,0,0,0,3,2,1,0,3,0,0,0,3,0,2,1,3,0,0,0,3,0,0,0,0
配列の場合:
1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0
戻り値:
4,4,3,4,3,4,2,4,3,4,2,4,3,4,1,4,3,4,1,4,0,4,4,3,4,3,4,2,4,3,4,2,4,3,4,1,4,3,4,1,4,0
これはきちんとした分布だと思います。中間配列をソートするアイデアを提供してくれた datdo に感謝します。