萧十郎
我决定将数据压缩为值和计数的关联数组,然后对数组从出现次数最多的到最少出现的进行排序。我循环遍历数组并仅处理第一个元素。我将值添加到输出数组,然后递减其计数并将其移动到下一个元素之后的位置。我内置了故障保护功能,以防止在不可能获得完美结果时出现无限循环。如果没有值出现多次,则永远不会进入循环。代码:(演示)function valueSeparator(array $array) { $maxIterations = count($array); $counted = array_count_values($array); arsort($counted); $iteration = 0; $result = []; while (max($counted) > 1 && $iteration < $maxIterations) { $count = reset($counted); $value = key($counted); $result[] = $value; unset($counted[$value]); arsort($counted); if ($count > 1) { $counted = array_merge( array_splice($counted, 0, 1), [$value => $count - 1], $counted ); } ++$iteration; } array_push($result, ...array_keys($counted)); var_export($result);}foreach ($arrays as $array) { valueSeparator($array); echo "\n---\n";}测试用例:$arrays = [ ['Retail', 'Retail', 'Food', 'Food', 'Retail'], ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'], ['Food'], ['Retail', 'Retail', 'Food', 'Retail'], ['Retail', 'Retail', 'Retail', 'Food', 'Food', 'Food', 'Charity', 'Charity', 'Charity'], ['Charity', 'Entertainment', 'Retail', 'Retail' ,'Retail']];输出:array ( 0 => 'Retail', 1 => 'Food', 2 => 'Retail', 3 => 'Food', 4 => 'Retail',)---array ( 0 => 'Retail', 1 => 'Entertainment', 2 => 'Food', 3 => 'Retail', 4 => 'Entertainment', 5 => 'Charity', 6 => 'Transport', 7 => 'Cosmetics',)---array ( 0 => 'Food',)---array ( 0 => 'Retail', 1 => 'Food', 2 => 'Retail', 3 => 'Retail',)---array ( 0 => 'Retail', 1 => 'Food', 2 => 'Charity', 3 => 'Retail', 4 => 'Food', 5 => 'Charity', 6 => 'Retail', 7 => 'Food', 8 => 'Charity',)---array ( 0 => 'Retail', 1 => 'Charity', 2 => 'Retail', 3 => 'Entertainment', 4 => 'Retail',)---
慕码人2483693
我尝试将排序数组保持在靠近输入数组的位置。首先,我从数组中删除任何不适合的元素,然后尝试稍后插入它们。如果剩下任何元素,我会遍历数组,将它们插入到任何合适的位置,避免无限循环。结果你得到 2 个数组,一个已排序,另一个找不到合适的位置: $input = ['Charity','Retail','Retail','Retail','Retail', 'Retail' ,'Retail', 'Charity', 'Charity', 'Charity','a' ];$laRest = [];$sorted = [];$laNoPlace = [];while(count($input) >0) { for ($i = 0; $i < count($laRest); $i++) { if(isset($laRest[$i]) && $laRest[$i] != end($sorted)) { $sorted[] = $laRest[$i]; unset($laRest[$i]); } } $laRest = array_values($laRest); $lsElement = array_shift($input); if (end($sorted) != $lsElement) { $sorted[] = $lsElement; } else { $laRest[] = $lsElement; }}if(count($laRest) >0) { while(count($laRest) >0) { $lsElement = array_shift($laRest); for ($i = 0; $i < count($sorted); $i++) { if($i != 0 && $sorted[$i] != $lsElement && !isset($sorted[$i+1]) && $lsElement !='') {//end array_push($sorted, $lsElement); $lsElement = ''; } if($i != 0 && $sorted[$i] != $lsElement && isset($sorted[$i+1]) && $sorted[$i+1] != $lsElement && $lsElement !='') { $lsStart = array_slice($sorted, 0, $i+1); $lsEnd = array_slice($sorted , $i+1); $sorted = array_merge($lsStart, array($lsElement), $lsEnd); $lsElement = ''; } if($i == 0 && $sorted[$i] != $lsElement && $lsElement !='') {//start array_unshift($sorted, $lsElement); $lsElement = ''; } } if($lsElement != '') { $laNoPlace[] = $lsElement; } }}print_r($sorted);echo "<HR>";print_r($laNoPlace);echo "<HR>";
繁星coding
我找到了一种排序方法,也许有人有更好的想法:<?php$array = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];$sorted = [];while (!empty($array)) { $current = current($array); if (end($sorted) !== $current) { $sorted[] = $current; array_splice($array, key($array), 1); } $next = next($array); if (!$next) { reset($array); shuffle($array); }}print_r($sorted);输出:Array( [0] => Retail [1] => Food [2] => Charity [3] => Entertainment [4] => Transport [5] => Entertainment [6] => Cosmetics [7] => Retail)另一个输入示例:$array = ['Retail', 'Retail', 'Retail', 'Retail', 'Retail', 'Food', 'Charity', 'Charity', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];输出:Array( [0] => Retail [1] => Food [2] => Retail [3] => Charity [4] => Retail [5] => Charity [6] => Retail [7] => Charity [8] => Entertainment [9] => Transport [10] => Entertainment [11] => Cosmetics [12] => Retail)针对特殊场合的更新代码,例如当输入是这样的时,['Retail', 'Retail', 'Food', 'Retail']在我的情况下是合理且可接受的:<?php$array = ['Retail', 'Retail', 'Food', 'Retail'];$sorted = [];$tries = 0;$maxTries = count($array);while (!empty($array) && $tries <= $maxTries) { $current = current($array); if (end($sorted) !== $current) { $sorted[] = $current; array_splice($array, key($array), 1); } $next = next($array); if (!$next) { reset($array); shuffle($array); $tries++; }}if (!empty($array)) { array_push($sorted, ...$array);}print_r($sorted);输出:Array( [0] => Retail [1] => Food [2] => Retail [3] => Retail)