Bảng băm VS mảng kết hợp


84

Gần đây tôi đã đọc về bảng băm trong một cuốn sách rất nổi tiếng " Giới thiệu về thuật toán ". Tôi chưa sử dụng chúng trong bất kỳ ứng dụng thực tế nào, nhưng tôi muốn. Nhưng tôi không biết bắt đầu như thế nào.
Bất cứ ai có thể cho tôi một số ví dụ về cách sử dụng nó, ví dụ, làm thế nào để nhận ra một ứng dụng từ điển (như ABBYY Lingvo) bằng cách sử dụng bảng băm?
Và cuối cùng tôi muốn biết sự khác biệt giữa bảng băm và mảng kết hợp trong PHP là gì, ý tôi là tôi nên sử dụng công nghệ nào và trong những trường hợp nào?
Nếu tôi sai (tôi xin thứ lỗi), hãy sửa cho tôi, bởi vì thực sự tôi đang bắt đầu với bảng băm và tôi chỉ có kiến ​​thức cơ bản (lý thuyết) về chúng.
Cảm ơn rất nhiều.


Câu trả lời:


123

Trong PHP, các mảng kết hợp được triển khai dưới dạng hashtables, với một chút chức năng bổ sung.

Tuy nhiên về mặt kỹ thuật, một mảng kết hợp không giống với một bảng băm - nó chỉ đơn giản được triển khai một phần với bảng băm đằng sau hậu trường. Bởi vì hầu hết việc triển khai của nó là một bảng băm, nó có thể làm mọi thứ mà một bảng băm có thể - nhưng nó cũng có thể làm được nhiều hơn thế.

Ví dụ: bạn có thể lặp qua một mảng kết hợp bằng vòng lặp for, điều mà bạn không thể làm với bảng băm.

Vì vậy, trong khi chúng tương tự nhau, một mảng kết hợp thực sự có thể thực hiện một tập hợp siêu tốc những gì một bảng băm có thể làm - vì vậy chúng không hoàn toàn giống nhau. Hãy nghĩ về nó như những hashtables cộng với chức năng bổ sung.

Ví dụ về mã:

Sử dụng một mảng kết hợp làm bảng băm :

$favoriteColor = array();
$favoriteColor['bob']='blue';
$favoriteColor['Peter']='red';
$favoriteColor['Sally']='pink';
echo 'bob likes: '.$favoriteColor['bob']."\n";
echo 'Sally likes: '.$favoriteColor['Sally']."\n";
//output: bob likes blue
//        Sally likes pink

Vòng qua một mảng kết hợp :

$idTable=array();
$idTable['Tyler']=1;
$idTable['Bill']=20;
$idTable['Marc']=4;
//up until here, we're using the array as a hashtable.

//now we loop through the array - you can't do this with a hashtable:
foreach($idTable as $person=>$id)
    echo 'id: '.$id.' | person: '.$person."\n";

//output: id: 1 | person: Tyler
//        id: 20 | person: Bill
//        id: 4 | person: Marc

Đặc biệt lưu ý cách trong ví dụ thứ hai, thứ tự của mỗi phần tử được duy trì (Tyler, Bill Marc) dựa trên thứ tự mà chúng được nhập vào mảng. Đây là sự khác biệt chính giữa mảng kết hợp và bảng băm. Một bảng băm không duy trì kết nối giữa các mục mà nó giữ, trong khi một mảng kết hợp PHP thì có (bạn thậm chí có thể sắp xếp một mảng liên kết PHP).


3
Hmmm, một lời giải thích ngắn gọn như vậy. Vậy chúng TUYỆT ĐỐI giống nhau?
Bakhtiyor

2
@Bak Họ không phải là nói chung, nhưng họ đang có trong PHP, mà đóng một chút nhanh và mất với cấu trúc dữ liệu kể từ khi có ít của một lo ngại về hiệu suất
Michael Mrozek

Tôi hiểu rồi, nhưng trong trường hợp này tại sao có rất nhiều thuật toán cho các hàm băm và những thứ như vậy, nếu hàm băm = mảng?
Bakhtiyor

4
@Michael bạn làm cho nó giống như một bất lợi? Nó làm cho PHP khác biệt, nhưng tôi nghĩ đó là một sự khác biệt tốt.

1
@Bakhityor: Câu cuối cùng của bạn thật hoàn hảo. Tuy nhiên, bạn không cần phải 'quên' về các hashtables - trên thực tế, thật tuyệt khi bạn đã hiểu về hashtables, bởi vì bây giờ bạn có thể áp dụng kiến ​​thức đó vào các mảng liên kết. Tôi đang thêm một số ví dụ vào câu trả lời của mình để làm rõ thêm điều cho bạn.
Cam

21

mảng php về cơ bản LÀ bảng băm


Chỉnh sửa: Ah - đánh bại tôi với nó :) +1.
Cam

đó là những gì tôi đang tìm kiếm :)
Faizan

10
Không đời nào. một bảng băm sẽ yêu cầu một số loại giải quyết xung đột, mà mảng php không có. Chiến lược giải quyết xung đột của họ chỉ là thay thế giá trị cũ và đó không phải là bảng băm theo định nghĩa.
Juan

4
Theo như tôi nhớ lại, việc giải quyết va chạm trong bảng băm là cho băm quan trọng, không phải là chìa khóa gốc (Làm thế nào nên rằng công việc thậm chí?)
Emanuel Oster

18

Sự khác biệt giữa mảng kết hợp và bảng băm là mảng kết hợp là một kiểu dữ liệu, trong khi bảng băm là một triển khai dữ liệu. Rõ ràng kiểu mảng kết hợp rất quan trọng trong nhiều ngôn ngữ lập trình hiện nay: Perl, Python, PHP, v.v ... Bảng băm là cách chính để triển khai một mảng kết hợp, nhưng không phải là cách duy nhất. Và mảng kết hợp là công dụng chính của bảng băm, nhưng không hoàn toàn là công dụng duy nhất. Vì vậy, không phải là chúng giống nhau, nhưng nếu bạn đã có các mảng liên kết, thì bạn thường không nên lo lắng về sự khác biệt.

Vì lý do hiệu suất, điều quan trọng cần biết là các mảng liên kết của bạn trong ngôn ngữ yêu thích của bạn được triển khai dưới dạng hàm băm. Và điều quan trọng là phải có một số ý tưởng về chi phí chung của việc triển khai đó. Bảng băm chậm hơn và sử dụng nhiều bộ nhớ hơn mảng tuyến tính như bạn thấy trong C.

Perl gộp hai khái niệm lại với nhau bằng cách gọi các mảng kết hợp là "băm". Giống như một số tính năng của Perl, nó không hoàn toàn sai, nhưng nó cẩu thả.


7

Một mảng trong PHP thực sự là một bản đồ có thứ tự, không phải bảng băm. Sự khác biệt chính giữa bản đồ và bảng băm bao gồm không thể nhớ thứ tự trong các phần tử đã được thêm vào. Mặt khác, hashtables nhanh hơn nhiều so với bản đồ. Độ phức tạp của việc tìm nạp một phần tử từ bản đồ là O (nlogn) và từ bảng băm là O (1).


4
"Độ phức tạp của việc tìm nạp một phần tử từ bản đồ là O (nlogn)" - điều này đơn giản là không đúng. Ngay cả đối với LinkedList, việc tìm nạp một phần tử đã cho chỉ là O (n). Thế nào là hơn, như đề cập ở en.wikipedia.org/wiki/Hash_table , bảng băm được sử dụng trong PHP để thực hiện một mảng kết hợp có tra cứu của O (1)
StackG

1
Như đã giải thích ở đây sau khi kiểm tra mã nguồn, các mảng kết hợp trong PHP được triển khai dưới dạng bảng băm trong đó "mỗi giá trị được lưu trữ trong hàm băm được liên kết với giá trị được lưu trữ trước nó và giá trị được lưu trữ sau" dưới dạng danh sách được liên kết. Vì vậy, nó sử dụng thêm bộ nhớ cho việc đó, nhưng việc truy cập một phần tử nhất định bằng cách sử dụng một khóa cũng nhanh như một bảng băm thông thường, O (1), không chậm hơn.
Leopoldo Sanczyk

2

Mảng kết hợp là một mảng mà bạn không truy cập các phần tử bằng chỉ mục mà bằng một khóa. Cách thức hoạt động nội bộ là việc thực hiện cụ thể (không có quy tắc nào nó phải hoạt động). Một mảng kết hợp có thể được thực hiện bởi một bảng băm (hầu hết các triển khai sẽ làm điều đó), nhưng nó cũng có thể được thực hiện bởi một số loại cấu trúc cây hoặc danh sách bỏ qua hoặc thuật toán chỉ lặp lại trên tất cả các phần tử trong mảng và tìm kiếm khóa phù hợp (điều này sẽ rất chậm, nhưng nó hoạt động).

Bảng băm là một cách lưu trữ dữ liệu trong đó các giá trị được liên kết với các khóa và nơi bạn định tìm các giá trị cho các khóa trong một thời gian (thường là gần như không đổi). Điều này nghe chính xác như những gì bạn mong đợi về một mảng kết hợp, đó là lý do tại sao hầu hết thời gian bảng băm được sử dụng để triển khai các mảng đó, nhưng điều đó không bắt buộc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.