我的任务是找到将字符串数组排列成字典顺序所需的步骤。
经过一番研究,我发现natsort()
做了同样的事情。但是我无法找到它的定义,也无法找到任何可以给我natsort()
所需步骤数的函数。
例如, 我有一个包含以下值的数组
以字典方式对此数组进行排序所需的步骤数为1
。
所以我有兴趣直接获取步骤数而不是实现任何排序算法。
感谢任何帮助。!
答案 0 :(得分:3)
natsort
在排序过程中使用特定的比较函数,也可以单独调用:strnatcmp
。
这意味着:
natsort($data);
...将产生与以下相同的结果:
usort($data, 'strnatcmp');
或者,更详细:
usort($data, function ($a, $b) {
return strnatcmp($a, $b);
});
这打开了计算此比较函数被调用次数的大门:
$count = 0;
usort($data, function ($a, $b) use (&$count) {
$count++;
return strnatcmp($a, $b);
});
例如:
$data = ['test', 'abc10', 'abc2', 'OK', 9, 13];
$count = 0;
usort($data, function ($a, $b) use (&$count){
$count++;
return strnatcmp($a, $b);
});
echo "$count comparisons: " . implode(", ", $data);
输出:
8次比较:9,13,OK,abc2,abc10,test
请注意,此排序算法区分大小写:" OK"在" abc"。
之前排序对于不区分大小写的自然排序,您可以使用natcasesort
和strnatcasecmp
无法使用上述方法知道在排序过程中有多少交换。 PHP在内部使用version of QuickSort,因此您可以模仿相同类型的算法并自行计算交换。由于以下原因,这显然是一种估计:
我将在这里提供我认为最标准算法的代码:它在给定分区的中间选择一个数据透视索引:
class QuickSort {
private static $swaps = 0;
private static $cmp = 'test';
private static function swap(&$array, $i, $j) {
if ($i == $j) return;
self::$swaps++;
list($array[$i], $array[$j]) = [$array[$j], $array[$i]];
}
private static function partition(&$array, $begin, $end) {
$cmp = self::$cmp;
$index = floor(($begin + $end) / 2);
$pivot = $array[$index];
self::swap($array, $index, $end);
for ($i = $index = $begin; $i < $end; $i++) {
if ($cmp($array[$i], $pivot) >= 0) continue;
self::swap($array, $index++, $i);
}
self::swap($array, $index, $end);
return $index;
}
private static function qsort(&$array, $begin, $end) {
if ($end <= $begin) return;
$index = self::partition($array, $begin, $end);
self::qsort($array, $begin, $index - 1);
self::qsort($array, $index + 1, $end);
}
public static function sort(&$array, $cmp = 'strcmp') {
self::$swaps = 0;
self::$cmp = $cmp;
self::qsort($array, 0, count($array) - 1);
return self::$swaps;
}
}
// Sample input
$data = [1,3,2,8,2,5,4,6];
// Call it: this sort function returns the number of swaps made
$swaps = QuickSort::sort($data, 'strnatcmp');
// Display the result:
echo "$swaps swaps: " . implode(", ", $data);
输出:
9 swaps: 1, 2, 2, 3, 4, 5, 6, 8
同样,在某些情况下,互换的数量可能比您预期的要多,因为快速排序并非专门设计用于最小化掉期数量。