2008-09-25 39 views
52

Tôi thường sử dụng bản đồ stdlib C++ bất cứ khi nào tôi cần lưu trữ một số dữ liệu được liên kết với một loại giá trị cụ thể (giá trị khóa - ví dụ: một chuỗi hoặc đối tượng khác). Việc triển khai bản đồ stdlib dựa trên các cây cung cấp hiệu suất tốt hơn (O (log n)) so với mảng tiêu chuẩn hoặc vector stdlib.Hashtable trong C++?

Câu hỏi của tôi là, bạn có biết bất kỳ triển khai có thể thực hiện nào có hiệu năng tốt hơn (O (1)) của C++ "chuẩn" hay không. Một cái gì đó tương tự như những gì có sẵn trong lớp Hashtable từ API Java.

Trả lời

74

Nếu bạn đang sử dụng C++ 11, bạn có quyền truy cập vào các tiêu đề <unordered_map><unordered_set>. Chúng cung cấp các lớp học std::unordered_mapstd::unordered_set.

Nếu bạn đang sử dụng C++ 03 với TR1, bạn có quyền truy cập vào các lớp std::tr1::unordered_mapstd::tr1::unordered_set, sử dụng các tiêu đề tương tự (trừ khi bạn đang sử dụng GCC, trong trường hợp các tiêu đề là <tr1/unordered_map><tr1/unordered_set> thay).

Trong mọi trường hợp, cũng có các loại tương ứng unordered_multimapunordered_multiset.

+6

Trong GCC, bạn phải sử dụng tên tiêu đề để thay thế. Đó là một cuộc trốn tránh của GCC. :-) –

+0

Gói tính năng VS2008 đã được thay thế bằng SP1. – Ferruccio

+0

IIRC Gói tính năng VC9 và SP1 tr1 :: unordered_ * việc triển khai đã được đưa ra khỏi các ghi chú phát hành về hiệu suất phụ tối ưu.Tôi cho rằng điều này sẽ được khắc phục cuối cùng. – jwfearn

1

Xem std::hash_map từ SGI.

Điều này cũng được bao gồm trong phân phối STLPort.

+0

Nó có thể được bao gồm trong STLPort, nhưng nó vẫn không "tiêu chuẩn", như câu hỏi sau này. Không có lớp _standard_ gọi là hash_map; nó được gọi là unordered_map thay vào đó, và nó trong TR1. –

3

Có một đối tượng hash_map như nhiều ở đây đã đề cập, nhưng nó không phải là một phần của stl. Nó là một phần mở rộng SGI, vì vậy nếu bạn đang tìm kiếm một cái gì đó trong STL, tôi nghĩ rằng bạn đang ra khỏi may mắn.

2

Visual Studio có lớp stdext::hash_map trong tiêu đề <hash_map> và gcc có lớp __gnu_cxx::hash_map trong cùng một tiêu đề.

+0

Nếu họ có cùng một giao diện, nó khá dễ dàng để thực hiện một triển khai hỗ trợ cả hai người trong số họ sử dụng bí danh không gian tên và một số công việc tiền xử lý. –

+0

Tôi biết, tôi biết, điều này không được chấp nhận. Không phải mọi đồng nghiệp đều có thể bị thuyết phục chuyển sang VS 2008 hoặc cài đặt Boost. Vì vậy, đây là một mẹo hay về cách kết hợp chúng lại với nhau: 'không gian tên std { #ifdef __GNUC__ \t sử dụng không gian tên __gnu_cxx; #elif \t sử dụng không gian tên stdext; #endif } ' – ypnos

1

hash_map cũng được hỗ trợ trong GNU libstdc++.

Dinkumware cũng supports điều này, có nghĩa là nhiều triển khai sẽ có hash_map (tôi nghĩ ngay cả Visual C++ cung cấp với Dinkumware).

+0

Nó có thể được hỗ trợ rộng rãi, nhưng nó không phải là" chuẩn ", như người hỏi hỏi. Chỉ các cơ sở TR1 mới có thể được coi là tiêu chuẩn. –

+0

Điểm tôi đã làm là nếu tất cả các nhà cung cấp trình biên dịch hỗ trợ nó (hoặc nhà cung cấp stdlibC++, như trường hợp có thể), thì nó có thể là một thay thế đủ tốt cho "tiêu chuẩn". BTW, TR1 không phải là "chuẩn". Nó được chấp nhận cho tiêu chuẩn tiếp theo, đủ để các nhà cung cấp thực hiện nó (quan điểm của tôi ...) –

+0

Tôi nghĩ đó chỉ là phiên bản libstdC++> = 4.0? – rogerdpack

16

Nếu bạn chưa có unordered_map hoặc unordered_set, chúng là một phần của boost.
Here's the documentation for both.

+0

Yay for Boost cung cấp _maximal portability_ một lần nữa. :-) Xem http://stackoverflow.com/questions/131445 cho một ví dụ khác về điều này. –

1

Nếu bạn có phần mở rộng TR1 có sẵn cho trình biên dịch yor, hãy sử dụng chúng. Nếu không, boost.org có một phiên bản khá giống ngoại trừ std :: namespace. Trong trường hợp đó, hãy đưa vào khai báo sử dụng để bạn có thể chuyển sang std :: later.

2

std :: tr1 :: unordered_map, trong <unordered_map>

nếu bạn không có tr1, có tăng, và sử dụng boost :: unordered_map trong <boost/unordered_map.hpp>