2016-01-12 13 views
9

array_udiffは、コールバック関数を使用して2つの配列の差を計算します。ただし、述語関数ではなく比較関数が必要です。なぜarray_udiffは述語関数の代わりに比較関数を使用しますか?

Aは、関数が項目Bに述語関数をアイテム相対比較比較するだけの項目A、項目Bに等しいか否かを決定するであろう

は、機能は通常正しい順序を決定するためにソート機能によって必要とされる比較。 array_udiffは違いを計算しているだけなので、各ペアが等しいかどうかを判断する述語関数は、十分であるように思えます。

なぜarray_udiffは述語関数の代わりに比較関数を使用しますか?代わりに述語を使用するかどうかは重要ですか?すなわち、01の戻り値を使用して、不等式と等価を表すことができます。-1の可能性は無視されますか?これは私の結果にどのような悪影響がありますか?

答えて

5

php_array_diff()(いくつかのユーザー空間配列関数の実装を提供する)の実装は、いくつかの内部比較関数を再利用することによって機能します。

これは、これらの比較関数がすでに他の目的のために存在し、必要なタスクを満たしているためです。つまり、2つのアイテムが等しいかどうかを判断する必要があります。彼らは少し余分な仕事をすることは重要ではありません。重要なのは、考慮する必要のあるコードの相対的な削減です。 (等価関数は比較関数や別のエンティティとして簡単に書くことができますが、同じ仕事をする2つの関数があります)

実際の実装はsortingでも動作します。ソートに適した比較アルゴリズムを使用する必要があります。そうしないと、予期しない結果が発生します。たとえば:

$a = [0, 1, 2, 3, 4, 5, 6]; 
$b = [4]; 

print_r(array_udiff($a, $b, function($x, $y) { 
    return $x <=> $y; //Sorting comparison function, correct 
})); 

print_r(array_udiff($a, $b, function($x, $y) { 
    return $x != $y; // Equality test, incorrect 
})); 

Array //Sorting comparison function, correct 
(
    [0] => 0 
    [1] => 1 
    [2] => 2 
    [3] => 3 
    [5] => 5 
    [6] => 6 
) 
Array // Equality test, incorrect 
(
    [0] => 0 
    [1] => 1 
    [2] => 2 
    [3] => 3 
    [4] => 4 // equality test causes udiff to incorrectly include 4 
    [5] => 5 
    [6] => 6 
) 

この理由は、()が使用するアルゴリズムphp_array_diffで提供します。基本的にはこのように書き:

  • 複製及びソート全てSRC
      の各要素について選別第一の入力アレイ
    • に等しいOUT出力を設定入力配列
    • Vは、現在の要素の値ですSRC
    • 各入力配列 が第二
      • から始まる>はVあるの次の要素に進んでください、私たちは== Vで過去1に行く場合は、ノートを作るために3210
      • Vの一致が見つかった場合は、OUTから削除してください。我々はありません(それは入力配列のままです)ならば、我々はそう新しいV> =現在の1

を持つまで

  • に先駆けSRCをスキップアルゴリズムはソートされているすべての入力に依存し、その事実(および比較関数)を使用するので、各入力配列の各要素を一度検査するだけで済みます。比較関数が実際にソートされた配列にならない場合、アルゴリズムは失敗し、結果は悪くなります。


    HHVMは異なるソートアルゴリズムを使用するため、HHVMは異なる結果になることがあります。 HHVMはpure quicksortを使用しますが、PHPは挿入ソートの最適化を含むquicksort implementation derived from llvmを使用します。

    通常、異なるソートアルゴリズムは、異なる方法で同じ解決策に到達します。すなわち、異なるアルゴリズムは、異なる順序、異なる時間、および異なる量で要素を比較させる。誤った比較関数の場合、これは配列の最終的な順序に大きな影響を与える可能性があります。

  • +0

    これは良い答えですが、アルゴリズムを使用してもそれに従うのは難しいです。あなたの例とアルゴリズムを使って、空の配列が期待される出力である理由を説明できますか? –

    +0

    [HHVMは述語関数をサポートしています](https://3v4l.org/8rOn0)に興味があります。また、2回目のテストでは、 '=='演算子は '!='でなければなりません。なぜなら '0'はマッチを表しているからです。 –

    0

    整列した配列を補完するには、安くなければなりません。ソートしないと、O(m * n)時間がかかります。

    関連する問題