12

これは非常に難解な質問ですが、私は本当に興味があります。今日、数年ぶりに usort を使用していますが、正確に何が起こっているのかに特に興味があります。次の配列があるとします。

$myArray = array(1, 9, 18, 12, 56);

これを usort でソートできます:

usort($myArray, function($a, $b){
  if ($a == $b) return 0;
  return ($a < $b) ? -1 : 1;
});

$a と $b という 2 つのパラメーターで何が起こっているのか、私には 100% 明確ではありません。彼らは何ですか、そして彼らは何を表していますか。つまり、$a が配列内の現在の項目を表していると想定できますが、これは正確には何と比較されているのでしょうか? $bとは?

配列を増やして文字列を含めることができます。

$myArray = array(
  array("Apples", 10),
  array("Oranges", 12),
  array("Strawberries", 3)
);

そして、次を実行します。

usort($myArray, function($a, $b){
  return strcmp($a[0], $b[0]);
});

そして、[0] インデックス値に基づいて、子配列をアルファベット順に並べ替えます。しかし、これは $a と $b が何であるかを明確にするものではありません。探しているパターンに一致することだけを知っています。

誰かが実際に何が起こっているかについて明確にすることができますか?

4

3 に答える 3

32

$a と $b の正確な定義は、配列のソートに使用されるアルゴリズムによって異なります。何かを並べ替えるには、2 つの要素を比較する手段が必要です。そのためにコールバック関数が使用されます。並べ替えアルゴリズムには、配列のどこからでも開始できるものもあれば、配列の特定の部分でのみ開始できるものもあるため、現在のアルゴリズムに従って比較する必要がある配列内の 2 つの要素であること以外に、$a と $b に固定された意味はありません。 .

このメソッドは、PHP が使用しているアルゴリズムを明らかにするために使用できます。

<?php

$myArray = array(1, 19, 18, 12, 56);

function compare($a, $b) {
    echo "Comparing $a to $b\n";
    if ($a == $b) return 0;
    return ($a < $b) ? -1 : 1;
}

usort($myArray,"compare");
print_r($myArray);
?>

出力

vinko@mithril:~$ php sort.php
Comparing 18 to 19
Comparing 56 to 18
Comparing 12 to 18
Comparing 1 to 18
Comparing 12 to 1
Comparing 56 to 19
Array
(
    [0] => 1
    [1] => 12
    [2] => 18
    [3] => 19
    [4] => 56
)

出力とソースを見ると、使用されている並べ替えが実際にクイックソートの実装であることがわかります。PHP ソースでZend/zend_qsort.cを確認してください(リンク先のバージョンは少し古いですが、あまり変更されていません)。

配列の中央にあるピボット (この場合は 18) を選択し、リストを並べ替えて、(使用中の比較関数に従って) ピボットよりも小さいすべての要素がピボットの前に来るようにする必要があります。ピボットよりも大きい要素はその後に続きます。最初にすべてを 18 と比較すると、それが行われていることがわかります。

さらに図式的な説明。

ステップ 0: (1,19,18,12,56); //ピボット: 18,
ステップ 1: (1,12,18,19,56); //最初の並べ替えの後
ステップ 2a: (1,12); //レッサーで同じことを再帰的に行います。
                         //pivot の 12 で、次に比較するのは
                         //出力を確認します。
ステップ 2b: (19,56); //そして、より大きなものでも同じことを行います
于 2009-07-07T11:23:27.840 に答える
5

何かを並べ替えるには、2 つの項目を比較して、一方が他方より前にあるかどうかを判断する手段が必要です。これはあなたが usort に提供するものです。この関数は、入力配列から 2 つの項目を渡され、それらが本来あるべき順序で返されます。

2 つの要素を比較する手段があれば、sort-algorithm-of-your-choice を使用できます。

慣れていない場合は、バブルソートのような単純な単純なアルゴリズムで比較関数がどのように使用されるかを確認してください。

舞台裏では、PHP はクイックソートを使用しています。

于 2009-07-07T11:16:40.507 に答える