[C++] map / multimap / unordered_map / unordered_multimap

2024. 11. 22. 11:39🧑🏻‍💻/C & C++

맵(map)

맵은 키-값 쌍을 저장하고 키를 기반으로 데이터를 검색하는 데 사용됩니다.
C++에서는 각 맵 타입의 동작 방식, 특징, 사용 목적에 따라 차이가 있습니다.
주요 map 타입들과 그 차이점을 정리하려 합니다.


1. std::map

  • 특징:
    • 키-값 쌍을 저장하며 키를 기준으로 정렬된 상태를 유지.
    • 내부적으로 레드-블랙 트리를 사용.
    • 키는 중복 불가능.
    • 키의 정렬 기준은 기본적으로 오름차순이며, 사용자 정의 가능.
  • 장점:
    • 정렬된 키 순서로 데이터를 순회 가능.
    • 키 검색, 삽입, 삭제가 O(log N).
  • 단점:
    • 중복 키가 필요하면 사용할 수 없음.
    • 삽입/삭제 시 추가적인 정렬 비용 발생.
  • 사용 예시:
#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap;
    myMap[1] = "One";
    myMap[3] = "Three";
    myMap[2] = "Two";

    for (const auto& [key, value] : myMap) {
        std::cout << key << ": " << value << '\n';
    }
    return 0;
}

2. std::multimap

  • 특징:
    • 키-값 쌍을 저장하며 키를 기준으로 정렬된 상태를 유지.
    • 키는 중복 가능.
    • 내부적으로 레드-블랙 트리를 사용.
  • 장점:
    • 중복 키를 지원하므로 동일한 키에 여러 값을 저장 가능.
    • 정렬된 키 순서로 데이터를 순회 가능.
  • 단점:
    • 키 검색, 삽입, 삭제가 O(log N).
    • 삽입 후 값 변경이 어려움 (std::map처럼 operator[]가 없음).
  • 사용 예시:
#include <iostream>
#include <map>

int main() {
    std::multimap<int, std::string> myMultimap;
    myMultimap.insert({1, "One"});
    myMultimap.insert({2, "Two"});
    myMultimap.insert({1, "Another One"});

    for (const auto& [key, value] : myMultimap) {
        std::cout << key << ": " << value << '\n';
    }
    return 0;
}

3. std::unordered_map

  • 특징:
    • 키-값 쌍을 저장하며 정렬되지 않은 상태를 유지.
    • 내부적으로 해시 테이블을 사용.
    • 키는 중복 불가능.
  • 장점:
    • 검색, 삽입, 삭제가 평균 O(1) (해시 충돌이 적을 경우).
    • 정렬이 필요 없는 경우 성능이 매우 우수.
  • 단점:
    • 해시 충돌이 많으면 최악의 경우 O(N).
    • 키 순서가 없으므로 순회 시 순서가 보장되지 않음.
  • 사용 예시:
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> myUnorderedMap;
    myUnorderedMap[1] = "One";
    myUnorderedMap[3] = "Three";
    myUnorderedMap[2] = "Two";

    for (const auto& [key, value] : myUnorderedMap) {
        std::cout << key << ": " << value << '\n';
    }
    return 0;
}

4. std::unordered_multimap

  • 특징:
    • 키-값 쌍을 저장하며 정렬되지 않은 상태를 유지.
    • 키는 중복 가능.
    • 내부적으로 해시 테이블을 사용.
  • 장점:
    • 중복 키를 지원하며, 검색, 삽입, 삭제가 평균 O(1).
    • 정렬이 필요 없는 경우 성능이 매우 우수.
  • 단점:
    • 해시 충돌이 많으면 최악의 경우 O(N).
    • 키 순서가 없으므로 순회 시 순서가 보장되지 않음.
  • 사용 예시:
#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_multimap<int, std::string> myUnorderedMultimap;
    myUnorderedMultimap.insert({1, "One"});
    myUnorderedMultimap.insert({2, "Two"});
    myUnorderedMultimap.insert({1, "Another One"});

    for (const auto& [key, value] : myUnorderedMultimap) {
        std::cout << key << ": " << value << '\n';
    }
    return 0;
}

맵들의 비교 표

특징 map multimap unordered_map unordered_multimap
정렬 여부 정렬됨 (키 기준) 정렬됨 (키 기준) 정렬되지 않음 정렬되지 않음
키 중복 허용 불가능 가능 불가능 가능
기본 구조 레드-블랙 트리 레드-블랙 트리 해시 테이블 해시 테이블
삽입/삭제/검색 시간 O(log N) O(log N) O(1) 평균, O(N) 최악 O(1) 평균, O(N) 최악
정렬된 순회 가능 여부 가능 가능 불가능 불가능

요약

  • 정렬이 필요하고 키가 중복되지 않으면: std::map
  • 정렬이 필요하고 키가 중복되면: std::multimap
  • 정렬이 필요 없고 키가 중복되지 않으면: std::unordered_map
  • 정렬이 필요 없고 키가 중복되면: std::unordered_multimap

각 상황에 따라 적합한 맵을 선택해 사용하면 됩니다. 😊

 

'🧑🏻‍💻 > C & C++' 카테고리의 다른 글

[C++] 순열, 조합  (0) 2024.10.05
[C++] vector  (0) 2024.09.28
[C++] Permutation, Combination  (0) 2024.08.10
[C] const  (0) 2022.09.15
[C] strjoin / strjoin.c / strjoin in c  (0) 2022.09.14