Làm cách nào để chọn giữa bản đồ và bản đồ không có thứ tự?


83

Giả sử tôi muốn ánh xạ dữ liệu với một chuỗi làm khóa. Tôi nên chọn thùng chứa nào, maphoặc unordered_map? unordered_mapchiếm nhiều bộ nhớ hơn, vì vậy hãy giả sử bộ nhớ không phải là một vấn đề, và mối quan tâm là tốc độ.

unordered_mapthường sẽ cho độ phức tạp trung bình của O (1) với trường hợp xấu nhất là O (n). Trong những trường hợp nào nó sẽ đến được O (n)? Khi nào thì mapthời gian hiệu quả hơn unordered_map? Nó có xảy ra khi n nhỏ không?

Giả sử tôi sẽ sử dụng STL unordered_mapvới hàm băm mặc định Vs. bản đồ. chuỗi là chìa khóa.

Nếu tôi sẽ lặp lại các phần tử thay vì truy cập một phần tử riêng lẻ mỗi lần, tôi có nên thích mapkhông?


3
Bạn có cần sắp xếp các mục trong ánh xạ không?
Một số anh chàng lập trình viên

Việc thực hiện nào unordered_mapsử dụng nhiều bộ nhớ hơn?
Peter Wood

Bạn luôn có chi phí bộ nhớ trong một bản đồ băm, mặc dù nó thường không đáng kể.
ypnos 10/12/12

Đó là một điểm nhỏ nhưng khi bạn đề cập đến việc lặp lại, cần chỉ ra rằng nếu bạn lặp lại trong khi chèn các phần tử, bạn nên ưu tiên bản đồ hơn là bản đồ không có thứ tự.
John McFarlane

Câu trả lời:


67

Trong thực tế, nếu bộ nhớ không có vấn đề, unordered_mapluôn nhanh hơn nếu bạn muốn truy cập phần tử đơn lẻ.

Trường hợp xấu nhất là về mặt lý thuyết và bị ràng buộc với một hàm băm duy nhất cho tất cả các phần tử. Điều này không liên quan đến thực tế. Càng unordered_mapchậm hơn ngay khi bạn có ít nhất nhật ký N phần tử thuộc cùng một hàm băm. Điều này cũng không liên quan đến thực tế. Trong một số trường hợp đặc biệt, bạn có thể sử dụng một thuật toán băm cụ thể để đảm bảo phân phối đồng đều hơn. Đối với các chuỗi thông thường không có chung một mẫu cụ thể, các hàm băm chung đi kèm unordered_mapcũng rất tốt.

Nếu bạn muốn duyệt qua bản đồ (sử dụng trình vòng lặp) theo cách được sắp xếp, bạn không thể sử dụng unordered_map. Ngược lại, mapkhông chỉ cho phép điều đó mà còn có thể cung cấp cho bạn phần tử tiếp theo trong bản đồ dựa trên giá trị gần đúng của khóa (xem lower_boundupper_boundphương pháp).


6
Câu trả lời này dễ gây hiểu lầm. Không đúng là "bản đồ không có thứ tự luôn nhanh hơn đối với truy cập phần tử đơn lẻ" - điều duy nhất tôi có thể nghĩ về điều đó luôn đúng là nó luôn được phân bổ nhanh hơn và tiệm cận . "Phân bổ" là một cảnh báo quan trọng trong practce: giả sử nó được triển khai dưới dạng bảng băm của một số loại, nếu tôi nhớ chính xác các bảng băm của mình, khi bạn phát triển nó bằng cách chèn các phần tử, nó sẽ "trục trặc" với một phép toán Ω (n) thường xuyên như vậy. Đó có thể là điều mà bất kỳ ứng dụng cụ thể nào cũng có thể chịu đựng được.
Don Hatch

209
                       | map              | unordered_map
---------------------------------------------------------
element ordering       | strict weak      | n/a 
                       |                  |
common implementation  | balanced tree    | hash table
                       | or red-black tree|  
                       |                  |
search time            | log(n)           | O(1) if there are no hash collisions
                       |                  | Up to O(n) if there are hash collisions 
                       |                  | O(n) when hash is the same for any key
                       |                  |     
Insertion time         | log(n)+rebalance | Same as search
                       |                  | 
Deletion time          | log(n)+rebalance | Same as search
                       |                  | 
needs comparators      | only operator <  | only operator ==
                       |                  |
needs hash function    | no               | yes
                       |                  |
common use case        | when good hash is| In most other cases. 
                       | not possible or  | 
                       | too slow. Or when|
                       | order is required| 

6
Nhận xét về cách thực hiện chung: Cây đỏ - đen là một loại cây cân bằng (hay cụ thể hơn là một loại cây tìm kiếm nhị phân tự cân bằng).
HelloGoodbye

2
tái cân bằng sẽ không mất nhiều hơnlog(n)
mtk

Điều gì về việc lặp lại trên tất cả các phần tử?
Shashwat

7

Trong những trường hợp nào nó sẽ đến được O (n)?

nếu bạn có một hàm băm xấu như vậy tạo ra cùng một giá trị băm cho tất cả các khuấy đầu vào (tức là tạo ra va chạm) ...

Tôi nên chọn vùng chứa nào, bản đồ hay bản đồ không có thứ tự?

Nó luôn là những câu hỏi về yêu cầu và loại / số lượng dữ liệu mà bạn có.

Khi nào một bản đồ có hiệu quả về thời gian hơn so với bản đồ không có thứ tự?

Nó chỉ là những cấu trúc khác nhau. Tốt hơn là bạn nên tạo một chiose để sử dụng một trong số chúng tùy thuộc vào các trường hợp sử dụng điển hình của bạn (tính đến loại dữ liệu bạn có và số lượng của nó)

Nó có hppaen khi n nhỏ không?

Trong trường hợp lượng dữ liệu nhỏ, mọi thứ phụ thuộc vào việc triển khai STL cụ thể ... Vì vậy, đôi khi ngay cả một vectơ / mảng đơn giản cũng có thể nhanh hơn các vùng chứa kết hợp ...


7

Tôi nên chọn vùng chứa nào, bản đồ hay bản đồ không có thứ tự? unardered_map chiếm nhiều bộ nhớ hơn, vì vậy hãy giả sử bộ nhớ không phải là một vấn đề và mối quan tâm là tốc độ.

Hồ sơ và sau đó quyết định. unordered_mapnói chung là nhanh hơn, nhưng nó thay đổi theo từng trường hợp.

Trong những trường hợp nào nó sẽ đến được O (n)?

Khi quá trình băm không tốt và một loạt các phần tử đang được gán vào cùng một thùng.

Khi nào một bản đồ có hiệu quả về thời gian hơn so với bản đồ không có thứ tự? Nó có hạnh phúc khi n còn nhỏ không?

Có lẽ là không, nhưng hãy sơ lược nó nếu bạn thực sự quan tâm. Có một vùng chứa với kích thước nhỏ là nút thắt cổ chai của chương trình của bạn dường như rất khó xảy ra. Dù sao, một đơn giản vectorvới tìm kiếm tuyến tính có thể nhanh hơn cho những trường hợp như vậy.


Điều quan trọng nhất khi quyết định là các yêu cầu về thứ tự và thiếu hiệu lực của trình lặp. Nếu bạn cần, bạn phải sử dụng khá nhiều map. Nếu không unordered_map,.

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.