Sự khác biệt giữa std :: multimap <key, value> và std :: map <key, std :: set <value>>


Câu trả lời:


51

Multimap lưu trữ các cặp (khóa, giá trị) trong đó cả khóa và giá trị có thể xuất hiện nhiều lần.

Di map<key, set<value>>chúc chỉ lưu trữ mỗi giá trị một lần cho một khóa cụ thể. Để làm được điều đó, nó sẽ phải có khả năng so sánh các giá trị, không chỉ các khóa.

Nó phụ thuộc vào ứng dụng của bạn nếu các giá trị so sánh bằng nhau là tương đương hoặc nếu bạn muốn lưu trữ chúng riêng biệt. Có lẽ chúng chứa các trường khác nhau nhưng không tham gia vào việc so sánh cho tập hợp.


5
Vì vậy, std :: multimap <key, value> giống như std :: map <key, std :: multiset <value>>, sự khác biệt giữa chúng là các giá trị sau này được sắp xếp. Có đúng không?
大 宝剑

2
Không, std::multimap<key, value>cho phép cùng một khóa xuất hiện nhiều lần trong khi std::map<key, whatever>yêu cầu tính duy nhất của key.
Yixing Liu

74

A std::maplà một vùng chứa liên kết, cho phép bạn có một khóa duy nhất được liên kết với giá trị kiểu của bạn. Ví dụ,

void someFunction()
{
    typedef std::map<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    auto it = myMap.find("test");
    if (it != myMap.end())
        std::cout << "value for " << it->first << " is " << it->second << std::endl;
    else
        std::cout << "value not found" << std::endl;
}

A std::multimapbằng a std::map, nhưng các khóa của bạn không còn là duy nhất nữa. Do đó, bạn có thể tìm thấy một loạt các mặt hàng thay vì chỉ tìm một mặt hàng duy nhất. Ví dụ,

void someFunction()
{
    typedef std::multimap<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("test", 45));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    std::pair<auto first, auto second> range = myMap.equal_range("test");
    for (auto it = range.first; it != range.second; ++it)
        std::cout << "value for " << it->first << " can be " << it->second << std::endl;
}

Các std::setgiống như một std::map, nhưng nó không được lưu trữ một chìa khóa liên quan đến một giá trị. Nó chỉ lưu trữ loại khóa và đảm bảo với bạn rằng nó là duy nhất trong bộ.

Bạn cũng có std::multiset, theo cùng một mô hình.

Tất cả các vùng chứa này cung cấp quyền truy cập O (log (n)) với find / equal_range của chúng.


6
Trong chức năng đa bản đồ, dòng std::pair<auto first, auto second> range = myMap.equal_range("test");này không hoạt động, bởi vì error: 'auto' not allowed in template argument. Sử dụng const auto range = myMap.equal_range("test")thay thế.
vancexu

2
loại bản đồ? Nó không phải là MapType trên dòng 4?
lolololol ol

không chắc chắn người đầu tiên, nhưng một rõ ràng là một bản sao dán của người kia: cppbuzz.com/What-is-difference-between-map-and-multimap
idclev 463035818

1
ahah, cppbuzz đang tìm kiếm StackOverflow hay sao ?, Tôi đã tự viết câu trả lời này nhiều năm trước khi tôi vẫn đang viết mã hàng ngày bằng c ++. Và có thực sự là một dòng typo 4, nhờ @lololololol
typedef

1
(và bản sao của họ / dán thất bại, họ thậm chí không hiển thị các loại trong mẫu std :: khai bản đồ: std :: map <std :: string, int>)
typedef

13
map::insert

Bởi vì vùng mapchứa không cho phép các giá trị khóa trùng lặp, thao tác chèn sẽ kiểm tra từng phần tử được chèn xem liệu phần tử khác đã tồn tại trong vùng chứa với cùng giá trị khóa hay chưa, nếu có thì phần tử không được chèn và giá trị được ánh xạ của nó không bị thay đổi theo bất kỳ cách nào.

Mặt khác

multimap::insert 

có thể chèn bất kỳ số lượng mục nào bằng cùng một khóa.

http://www.cplusplus.com/reference/stl/map/
http://www.cplusplus.com/reference/stl/multimap/


Liên kết tốt về cả sự khác biệt và cách nó hoạt động trong nội bộ. liên kết
Rndp13

10

Cái sau yêu cầu các giá trị có thể được sắp xếp (thông qua operator<hoặc một hàm so sánh), cái trước thì không.


Nó sẽ xuất hiện toán tử <hoạt động giống nhau trên bản đồ hoặc đa bản đồ? vi.cppreference.com/w/cpp/container/map/operator_cmp
johnbakers

Có, nhưng câu trả lời của tôi đề cập đến thứ tự của các giá trị. Giả sử bạn có một loại Tlà không có thứ tự. Bạn có thể sử dụng nó để tạo một std::multimap<U, T>, nhưng bạn không thể sử dụng để tạo một std::map<U, std::set<T> >.
Björn Pollex
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.