2012-01-28 28 views
10

Các Multimap trong C++ dường như làm việc thực sự kỳ lạ, tôi muốn biết tại saounordered_multimap - lặp lại kết quả của find() mang yếu tố có giá trị khác nhau

#include <iostream> 
#include <unordered_map> 

using namespace std; 

typedef unordered_multimap<char,int> MyMap; 

int main(int argc, char **argv) 
{ 
    MyMap map; 
    map.insert(MyMap::value_type('a', 1)); 
    map.insert(MyMap::value_type('b', 2)); 
    map.insert(MyMap::value_type('c', 3)); 
    map.insert(MyMap::value_type('d', 4)); 
    map.insert(MyMap::value_type('a', 7)); 
    map.insert(MyMap::value_type('b', 18)); 

    for(auto it = map.begin(); it != map.end(); it++) { 
     cout << it->first << '\t'; 
     cout << it->second << endl; 
    } 

    cout << "all values to a" << endl; 
    for(auto it = map.find('a'); it != map.end(); it++) { 
     cout << it->first << '\t' << it->second << endl; 
    } 

} 

đây là kết quả:

c 3 
d 4 
a 1 
a 7 
b 2 
b 18 
all values to a 
a 1 
a 7 
b 2 
b 18 

tại sao đầu ra vẫn chứa bất kỳ thứ gì có b làm khóa khi tôi yêu cầu 'a' một cách rõ ràng? Đây có phải là trình biên dịch hoặc lỗi stl không?

Trả lời

36

find, như được triển khai, trả về một trình lặp cho phần tử đầu tiên khớp với khóa trong bội số (như với bất kỳ bản đồ nào khác). Bạn có thể tìm kiếm equal_range:

// Finds a range containing all elements whose key is k. 
// pair<iterator, iterator> equal_range(const key_type& k) 
auto its = map.equal_range('a'); 
for (auto it = its.first; it != its.second; ++it) { 
    cout << it->first << '\t' << it->second << endl; 
} 
+0

Nếu bạn thay đổi -> để. sau đó tôi sẽ chấp nhận câu trả lời của bạn. – Arne

+1

Tôi nhận được '->' hạnh phúc. – user7116

-1

Có vẻ như bạn nhận được một iterator vào "danh sách" đầy cặp, bắt đầu từ cặp đầu tiên với 'a' vì nó là chìa khóa. Vì vậy, khi bạn lặp lại đến cùng, tự nhiên bạn sẽ nhận được mọi thứ vượt quá 'a'. Nếu bạn tìm kiếm 'c', có thể bạn sẽ lặp lại toàn bộ "danh sách" làm những gì bạn làm ở đó. Có lẽ bạn nên lặp lại thành "it! = Map.end() & & it-> first == 'a'" nếu bạn muốn tất cả của a.

8

Đó không phải là lỗi, đó là do thiết kế. find trả về một trình lặp cho một trong các phần tử phù hợp, đó là tất cả. Bạn sẽ lặp lại đến cuối bản đồ với cấu trúc của bạn.

Bạn cần sử dụng multimap::equal_range để thực hiện những gì bạn đang làm sau.

4

Có một ví dụ trong www.cplusplus.com, về Cách sử dụng phương thức equal_range để nhận tất cả các phần tử có cùng khóa.

// unordered_multimap::equal_range 
#include <iostream> 
#include <string> 
#include <unordered_map> 
#include <algorithm> 

typedef std::unordered_multimap<std::string,std::string> stringmap; 

int main() 
{ 
    stringmap myumm = { 
    {"orange","FL"}, 
    {"strawberry","LA"}, 
    {"strawberry","OK"}, 
    {"pumpkin","NH"} 
    }; 

    std::cout << "Entries with strawberry:"; 
    auto range = myumm.equal_range("strawberry"); 
    for_each (
    range.first, 
    range.second, 
    [](stringmap::value_type& x){std::cout << " " << x.second;} 
); 

    return 0; 
} 

Vui lòng tham khảo link: http://www.cplusplus.com/reference/unordered_map/unordered_multimap/equal_range/

+0

@einpoklum Đây là ** một câu trả lời ** trước khi xóa, vui lòng đọc siêu dữ liệu này [bạn đang thực hiện-sai-sai-một-lời-xin-san-trong-hàng-thấp-chất-bài-hàng đợi] (http://meta.stackoverflow.com/questions/287563/youre-doing-it-wrong-a-plea-for-sanity-in-the-low-quality-posts-queue) –

+0

Hãy để tôi nói lại điều đó (cơ chế đánh giá không ' t cho phép bạn đưa ra các nhận xét cụ thể và bạn chọn từ danh sách): OP hỏi "Tại sao X lại xảy ra?" - câu trả lời của bạn, trong khi có thể hữu ích nói chung, không phải là một lời giải thích về những gì xảy ra với mã của OP. Vì vậy, không phải là một câu trả lời. – einpoklum

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