3 回答

TA貢獻1815條經驗 獲得超13個贊
我決定將數據壓縮為值和計數的關聯數組,然后對數組從出現次數最多的到最少出現的進行排序。我循環遍歷數組并僅處理第一個元素。我將值添加到輸出數組,然后遞減其計數并將其移動到下一個元素之后的位置。
我內置了故障保護功能,以防止在不可能獲得完美結果時出現無限循環。
如果沒有值出現多次,則永遠不會進入循環。
代碼:(演示)
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',
)
---

TA貢獻1860條經驗 獲得超9個贊
我嘗試將排序數組保持在靠近輸入數組的位置。首先,我從數組中刪除任何不適合的元素,然后嘗試稍后插入它們。如果剩下任何元素,我會遍歷數組,將它們插入到任何合適的位置,避免無限循環。結果你得到 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>";

TA貢獻1797條經驗 獲得超4個贊
我找到了一種排序方法,也許有人有更好的想法:
<?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
)
- 3 回答
- 0 關注
- 162 瀏覽
添加回答
舉報