在最小交换中查找周期的php实现

时间:2018-12-18 17:55:02

标签: php arrays sorting

找出使数组排序所需的最小相邻交换数。

我使用的方法是在数组中找到一个重复的循环,例如3-> 1-> 4-> 2是4的循环,因此最小交换数为3,输入为[3,1,4,2,5]使它排序[1,2,3,4,5]

我有三个数组,$ old包含未排序的数组,$ arr已排序,$ bool计算是否访问了该位置

$old = $arr;
quicksort($arr, 0, count($arr) - 1);
$bool = array_fill(0, count($arr), false);
$count = 0;
$circle = 0;

for ($i = 0; $i < count($bool); $i++){
    if ($arr[$i] !== $old[$i]) {
        $circle ++;

        $where = array_search($old[$i], $arr);

        $bool[$i] = true;

        if ($bool[$where]) {
            $count += $circle;
            $circle = 0;
        }
    }
}
return $count;

这个想法是跳过已经在正确索引中的元素

并标记未标记的元素,保持周期计数(我使用$ circle),一旦已经标记了正确的位置,我就得出到达一个周期的结论,

但是这种逻辑不符合我的预期,需要一些帮助。

1 个答案:

答案 0 :(得分:0)

我认为您追求的是这样,但是我可能错了。 我尝试通过很多循环使其保持简单以使其正常运行,并解释了代码中的不同步骤

<?php

$minSize = 3;
$arr  = [3,1,2,6,9,3,5,2,6,9,3,5,1,8,4,6,6,9,3,0];
$repeats = [];

//outer loop
for($i = 0; $i < count($arr); $i++) {
    $currValue = $arr[$i];
    //get all the keys for where the value is the same as $currValue
    //this gives a starting position to test our matching sets
    $matches = array_keys($arr, $currValue);
    //match loop
    for($j = 0; $j < count($matches); $j++) {
        $leftIndex = $currValue; //this needs to be reset for every set
        $matchIndex = $matches[$j];
        //now we do want matches only when the index is different, always it will always match
        if($leftIndex === $matchIndex) {
            continue;
        }

        $subsequentMatch = 0;
        //isset so we don't go out of bounds of our array
        while(isset($arr[$leftIndex], $arr[$matchIndex]) && $arr[$leftIndex] === $arr[$matchIndex]) {
            $subsequentMatch++;
            $leftIndex++;
            $matchIndex++;
        }

        if($subsequentMatch >= $minSize) {
            $repeats[] = array_slice($arr, $currValue, $subsequentMatch) ;
        }
    }
}

print_r($repeats);

在此处查看示例:https://3v4l.org/cBWQ5

您可以通过

对此进行改进

for($ i = 0; $ i <(count($ arr)-$ minSize); $ i ++){

因为如果该集合位于$minSize下,它将永远不会添加到重复序列中

编辑:根据评论,OP可能正在寻找这个?

<?php

$arr  = [3,1,2,6,9,3,5,2,6,9,3,5,1,8,4,6,6,9,3,0];
$swapCount = 0;
usort($arr, function ($a, $b) use (&$swapCount) {
    if($a === $b) {
        return 0;
    }
    $swapCount++;
    return $a <=> $b;
});

echo 'Arr Count: ' . count($arr) . PHP_EOL;
echo 'Swaps performed: ' . $swapCount;

这是一个简单的排序,我想您可以编写一个usort并使用每种不同的排序机制进行计数(列表是无穷的),然后找出该值的最小值

排序机制列表浮出水面

  • 插入排序
  • 气泡排序
  • 快速排序
  • 计数排序
  • 梳理排序
  • 堆排序
  • 合并排序
  • 壳牌排序
  • 奇数排序

您可以在Google上搜索如何在PHP中实现这些功能,也许还有更多方法。