메뉴 닫기

STL multimap 제대로 이해하기, 중복 키가 필요한 순간


STL multimap 제대로 이해하기, 중복 키가 필요한 순간

🔍 map과는 다릅니다, 중복 키를 허용하는 multimap의 진짜 매력

C++을 배우거나 STL 컨테이너를 다뤄본 적이 있다면 map은 익숙할 수 있습니다.
하지만 키 중복이 필요한 상황에서는 map만으로는 부족하다는 점, 알고 계셨나요?
이럴 때 유용한 컨테이너가 바로 multimap입니다.
특히 여러 개의 값을 같은 키에 저장해야 하는 상황에서 강력한 기능을 발휘하죠.
오늘은 STL multimap의 특징과 사용법, 그리고 map과의 차이까지 친절하게 풀어드릴게요.

이 글에서는 C++ STL의 핵심 컨테이너 중 하나인 multimap에 대해 다룹니다.
기본적인 구조와 작동 원리부터, 실제 사용 예시, 그리고 map과의 차이점까지 차근차근 살펴보며,
중복 키가 필요한 상황에서 왜 multimap이 더 적합한 선택인지 이해하실 수 있도록 안내해 드릴게요.
개발자라면 꼭 알아야 할 multimap의 모든 것을 담았습니다.







🧱 STL multimap이란?

C++ 표준 템플릿 라이브러리(STL)에서 제공하는 multimap연관 컨테이너(associative container) 중 하나로, 중복 키를 허용하는 map입니다.
즉, 하나의 키에 대해 여러 개의 값을 저장할 수 있는 자료구조죠.

map은 키가 고유해야 하는 반면, multimap은 동일한 키로 여러 데이터를 저장할 수 있기 때문에,
예를 들어 한 학생의 이름에 여러 개의 성적 항목을 매칭하거나, 하나의 단어에 여러 번역어를 저장하는 등 1:N 관계 데이터를 다룰 때 유용합니다.

💎 핵심 포인트:
multimap은 키를 기준으로 자동 정렬되며, 내부적으로 Red-Black Tree 기반의 균형 이진 탐색 트리로 구현되어 있습니다.

📌 multimap의 주요 특징

  • 📌중복 키 허용: 동일한 키로 여러 쌍 저장 가능
  • 📌자동 정렬: 키를 기준으로 자동으로 정렬된 상태 유지
  • 📌O(log n)의 탐색, 삽입, 삭제 시간복잡도 보장
  • 📌lower_bound, upper_bound와 같은 탐색 함수 제공

이처럼 multimap은 데이터를 효율적으로 그룹화하고 저장할 수 있도록 도와주는 유용한 컨테이너입니다.
특히 데이터의 관계가 다대일(N:1) 또는 다대다(N:N)인 구조라면, vector나 list보다 훨씬 직관적인 처리가 가능합니다.


🆚 map과 multimap의 핵심 차이

C++ STL에서 mapmultimap은 둘 다 키-값 쌍(key-value pair)을 저장하는 컨테이너입니다.
하지만 이 둘은 키의 중복 허용 여부데이터 삽입/탐색 방식에서 분명한 차이가 있습니다.

📌 비교 포인트 정리

항목 map multimap
키 중복 허용 ❌ 불가 ✅ 가능
기존 키 삽입 시 기존 값 덮어쓰기 추가 삽입
탐색 함수 find, at equal_range, lower_bound, upper_bound
사용 목적 고유 키 기반 매핑 중복 키 매핑

이처럼 map은 중복 키를 허용하지 않는 반면, multimap은 동일한 키에 대해 여러 개의 데이터를 저장할 수 있기 때문에 활용 범위가 다릅니다.
어떤 컨테이너를 선택할지는 사용하는 데이터의 특성과 목적에 따라 결정해야 하죠.

💬 동일한 키를 여러 번 등록할 가능성이 있다면, 고민 없이 multimap을 사용하세요.







💡 중복 키가 필요한 상황은?

중복된 키를 허용하는 multimap은 일반적인 map으로는 처리하기 어려운 특정 데이터 구조에 매우 적합합니다.
특히 다음과 같은 케이스에서 multimap이 큰 장점을 발휘하죠.

  • 🎓학생 이름을 키로 하여 여러 과목 점수를 저장할 때
  • 📚단어 하나에 여러 개의 뜻이나 번역을 매칭해야 할 때
  • 🏢회사명으로 다수의 직원 데이터를 연결할 때
  • 📆날짜별로 중복되는 일정을 관리해야 할 때

예를 들어 영어 단어 “bank”는 금융기관, 강둑, 저장소 등 다양한 뜻을 가질 수 있습니다.
이럴 때 map은 한 가지 뜻만 저장할 수 있지만, multimap은 모든 뜻을 키 “bank”에 연결하여 검색과 관리가 훨씬 쉬워집니다.

💎 핵심 포인트:
multimap은 데이터 간의 다대일(N:1) 또는 다대다(N:N) 관계를 효과적으로 표현할 수 있습니다.

반면 중복이 없고 키 하나에 딱 하나의 값만 대응되는 구조라면, map이 더 효율적입니다.
상황에 맞는 컨테이너 선택이 개발자의 설계 역량을 보여주는 중요한 요소이기도 하죠.


🔧 multimap 기본 문법과 사용 예시

multimap은 기본적으로 #include <map> 헤더에 정의되어 있으며, 템플릿을 활용해 multimap<Key, Value> 형태로 선언합니다.
각 키에 대해 여러 값을 저장할 수 있으며, 삽입 시에도 특별한 설정 없이 동일한 키를 여러 번 추가할 수 있습니다.

CODE BLOCK
#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores;

    scores.insert({"Alice", 90});
    scores.insert({"Bob", 85});
    scores.insert({"Alice", 95}); // 중복 키 허용

    for (auto& entry : scores) {
        cout << entry.first << " : " << entry.second << endl;
    }
    return 0;
}

위 예제에서는 “Alice”라는 동일한 키에 대해 두 개의 값(90, 95)이 삽입되었습니다.
multimap은 이 값을 모두 저장하며, 자동으로 키 순으로 정렬해 출력합니다.

📌 특정 키로 모든 값 찾기

특정 키로 저장된 모든 값을 가져오고 싶다면 equal_range 함수를 사용할 수 있습니다.

CODE BLOCK
auto range = scores.equal_range("Alice");
for (auto it = range.first; it != range.second; ++it) {
    cout << it->first << " : " << it->second << endl;
}

위 방식은 특정 키를 가진 모든 값을 탐색하는 데 매우 유용하며,
map에서는 불가능한 multimap만의 특징적인 기능입니다.

💡 TIP: insert 대신 emplace를 사용하면 객체 복사 비용을 줄일 수 있어 성능적으로 더 효율적입니다.







🚀 성능과 주의사항

multimap은 많은 장점을 제공하지만, 성능적인 측면이나 사용 방식에 따라 주의해야 할 점들도 분명히 존재합니다.
특히 대용량 데이터를 다루거나 키 충돌이 잦은 환경에서는 이러한 요소를 잘 이해하고 사용하는 것이 중요합니다.

📌 성능 이슈

multimap은 내부적으로 균형 이진 탐색 트리(Red-Black Tree) 구조를 사용하여 삽입, 삭제, 탐색 모두 O(log n)의 시간복잡도를 보장합니다.
그러나 중복 키가 많은 경우에는 탐색 범위가 넓어질 수 있어 속도 저하가 발생할 수 있습니다.

⚠️ 주의: 삽입 순서가 보장되지 않기 때문에, 키의 삽입 순서를 기준으로 순회를 기대하면 안 됩니다.

📌 사용 시 고려사항

  • 🧠중복된 키의 값은 equal_range 또는 반복자 범위로 순회
  • 🧹특정 키에 해당하는 모든 값을 삭제하려면 erase(key) 사용
  • 자주 사용되는 키가 있다면 unordered_multimap을 고려 (해시 기반)

또한, 요소를 반복문에서 순회할 때 iterator invalidation에 유의해야 합니다.
삭제와 삽입이 반복되는 로직에서는 반복자가 무효화되어 예기치 않은 동작이 발생할 수 있기 때문이죠.

💎 핵심 포인트:
중복 키가 많거나 빈번한 탐색이 필요한 경우에는 자료구조의 선택이 성능에 결정적인 영향을 미칠 수 있습니다.


❓ 자주 묻는 질문 (FAQ)

multimap은 내부적으로 어떤 구조로 동작하나요?
multimap은 Red-Black Tree 기반의 이진 탐색 트리로 구현되어 있어, 삽입, 삭제, 탐색이 모두 O(log n)의 시간복잡도로 처리됩니다.
map 대신 multimap을 써야 하는 대표적인 상황은?
하나의 키에 여러 값을 연결해야 하는 경우입니다. 예를 들어 같은 날짜에 여러 일정이 있는 경우나, 하나의 단어에 여러 번역이 있는 상황이 해당됩니다.
multimap은 삽입 순서를 보장하나요?
아닙니다. multimap은 삽입 순서가 아닌 키 값에 따라 자동으로 정렬되기 때문에, 삽입한 순서대로 데이터가 정렬되지 않습니다.
중복된 키의 모든 값을 어떻게 탐색하나요?
equal_range 함수를 사용하면 특정 키에 해당하는 모든 값의 범위를 반복자로 받아 순회할 수 있습니다.
multimap에서 erase(key)를 호출하면 어떻게 되나요?
해당 키를 가진 모든 키-값 쌍이 삭제됩니다. 중복된 키가 모두 제거되는 방식이므로 주의해서 사용해야 합니다.
unordered_multimap과의 차이는 뭔가요?
unordered_multimap은 해시 기반 컨테이너로, 정렬은 보장되지 않지만 평균적으로 더 빠른 탐색 속도를 제공합니다.
multimap에 저장된 데이터를 vector로 바꿀 수 있나요?
네, 반복문을 사용해 multimap의 각 요소를 vector에 복사하면 가능합니다. 다만 키의 정렬 순서가 유지되지 않을 수 있습니다.
multimap에서 특정 키-값 쌍만 삭제할 수 있나요?
가능합니다. 특정 반복자를 통해 정확한 키-값 위치를 지정하고 erase(iter)를 사용하면 원하는 쌍만 삭제할 수 있습니다.



🧠 STL multimap, 중복 키를 다루는 스마트한 방법

STL의 multimap은 중복 키를 허용해야 하는 상황에서 탁월한 선택입니다.
단일 키에 여러 개의 값을 저장할 수 있어 1:N 또는 다대다 관계의 데이터를 직관적으로 표현할 수 있죠.
map과의 차이, 주요 기능, 사용 예시를 통해 multimap의 핵심 개념을 쉽게 이해하셨을 거라 생각합니다.

equal_range, lower_bound, upper_bound와 같은 탐색 도구를 잘 활용하면 중복된 키를 빠르고 유연하게 다룰 수 있으며,
erase나 emplace 같은 함수로 메모리 관리 및 성능 최적화도 가능합니다.
성능상의 유의점도 함께 살펴봤으니, 여러분의 개발 상황에 맞게 올바른 컨테이너 선택을 하시길 바랍니다.

이제 단순한 map을 넘어서, 복잡한 관계형 데이터를 다룰 때 multimap의 진가를 제대로 발휘해보세요.


🏷️ 관련 태그 : multimap, C++STL, 중복키, map차이점, equal_range, STL컨테이너, 키값저장, 자료구조, C++기초, RedBlackTree