2016-01-12 13 views
9

array_udiff tính toán sự khác biệt giữa hai mảng sử dụng hàm gọi lại. Tuy nhiên, nó đòi hỏi một hàm so sánh thay vì hàm vị ngữ.Tại sao array_udiff sử dụng hàm so sánh thay vì hàm vị ngữ?

Một so sánh chức năng so sánh mục A tương ứng với mục B. Một chức năng vị ngữ sẽ chỉ xác định có hay không mục A là tương đương với mục B.

Hãy so sánh các chức năng thường được yêu cầu của chức năng sắp xếp để xác định thứ tự đúng. Kể từ array_udiff chỉ là tính toán sự khác biệt, một chức năng vị ngữ xác định xem mỗi cặp là bằng nhau có vẻ như nó là đủ.

Tại sao array_udiff sử dụng hàm so sánh thay vì hàm vị ngữ? Liệu nó có quan trọng nếu tôi sử dụng một vị từ thay thế? tức là tôi có thể chọn chỉ sử dụng các giá trị trả về 01 để biểu thị sự bất bình đẳng và bình đẳng, loại bỏ khả năng -1 không? Tác dụng bất lợi, nếu có, điều này có ảnh hưởng đến kết quả của tôi không?

Trả lời

5

Việc triển khai cho php_array_diff() (cung cấp triển khai cho một số hàm mảng không gian người dùng) hoạt động bằng cách sử dụng lại một số hàm so sánh nội bộ.

Điều này là do các hàm so sánh đó đã tồn tại cho các mục đích khác và đáp ứng được nhiệm vụ cần thiết trong tầm tay: xác định xem hai mục có bằng nhau hay không. Rằng họ làm thêm một chút công việc là không quan trọng; điều quan trọng là giảm mã tương đối cần được xem xét. (Một hàm bằng có thể dễ dàng được viết theo một hàm so sánh, hoặc là một thực thể riêng biệt, nhưng bây giờ bạn có hai hàm để thực hiện cùng một công việc.)

Việc thực hiện thực tế cũng hoạt động theo số sorting. Vì vậy, bạn cần sử dụng thuật toán so sánh phù hợp để sắp xếp hoặc bạn sẽ nhận được kết quả không mong muốn. Ví dụ:

$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 
})); 

cho

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 
) 

Lý do cho điều này là php_array_diff thuật toán() sử dụng. Về cơ bản nó đi như thế này:

  • trùng lặp và sắp xếp tất cả các mảng đầu vào
  • Đặt ra OUT bằng với sắp xếp đầu tiên mảng đầu vào
  • Đối với mỗi phần tử trong SRC
    • V là giá trị của phần tử hiện tại trong SRC
    • Đối với mỗi mảng đầu vào Một bắt đầu từ thứ hai
      • Bỏ qua trước để các phần tử tiếp theo trong Một đó là>V, nhưng làm cho một lưu ý nếu chúng tôi đi một quá khứ mà là == V.
      • Nếu chúng tôi tìm thấy kết quả phù hợp cho V, hãy xóa nó khỏi OUT.
      • Nếu chúng ta không (vì vậy nó vẫn trong mảng đầu vào), bỏ qua trong SRC cho đến khi chúng tôi có một mới V> = dòng điện một

Vì vậy, , thuật toán dựa trên tất cả các đầu vào đang được sắp xếp và sử dụng thực tế đó (và hàm so sánh) để nó chỉ phải kiểm tra từng phần tử trong mỗi mảng đầu vào một lần. Nếu hàm so sánh không dẫn đến một mảng được sắp xếp thực sự, thuật toán thất bại và bạn sẽ nhận được kết quả xấu.


HHVM có thể dẫn đến kết quả khác, vì HHVM sử dụng thuật toán phân loại khác. HHVM sử dụng pure quicksort, trong khi PHP sử dụng một quicksort implementation derived from llvm bao gồm tối ưu hóa sắp xếp chèn.

Thông thường, các thuật toán phân loại khác nhau đến cùng một giải pháp thông qua các phương tiện khác nhau. Đó là, các thuật toán khác nhau khiến các phần tử được so sánh theo thứ tự khác nhau, vào các thời điểm khác nhau và với số lượng khác nhau. Trong trường hợp của một hàm so sánh không chính xác, điều này có thể có ảnh hưởng lớn đến thứ tự cuối cùng của mảng.

+0

Đây là câu trả lời hay, nhưng ngay cả với thuật toán, thật khó để theo dõi. Bạn có thể giải thích, sử dụng ví dụ của bạn và thuật toán, tại sao một mảng trống là đầu ra mong đợi? –

+0

Thật thú vị khi lưu ý rằng [HHVM hỗ trợ chức năng biến vị ngữ] (https://3v4l.org/8rOn0). Ngoài ra, trong bài kiểm tra thứ hai của bạn, toán tử '==' phải là '! =' Vì '0' đại diện cho một trận đấu. –

0

Nó phải rẻ hơn để bổ sung các mảng đặt hàng. Không phân loại nó sẽ mất thời gian O (m * n).

Các vấn đề liên quan