728x90
728x90

multimap(멀티 맵)

특징

  • map과 거의 동일하지만, 키(Key) 값이 중복 가능한 컨테이너
  •  키(Key)값(Value)이 삽입될 때, 키(Key)가 정렬이 되면서 삽입된다.

멀티 맵의 구조

 

헤더 파일

  • 멀티 맵을 사용하려면 다음의 헤더 파일을 불러와야 한다.
#include <map>

 

멤버 함수

 

사용 방법

 

[C++] 맵(Map)

맵(Map) 특징 연관 컨테이너(Associative Container) 중 하나이다. 연관 컨테이너에는 set, multiset, map, multimap 이 있다. string : int 형태로 값을 할당해야 할 때 맵을 사용한다. 키(Key)와 값(Value) 형태로 이루

dev-astra.tistory.com

 

객체 생성

  • 다음과 같이 객체를 생성한다.
multimap<[data_type_1], [data_type_2]> [name]
#include <iostream>
#include <map>
using namespace std;

multimap<int, string> mm {
    { 2, "10" },
    { 1, "30" },
    { 1, "20" },
    { 1, "30" }
};

int main() {
    for (const auto& [key, value] : mm) {
        cout << key << " : " << value << endl;
    }
    
    return 0;
}
1 : 30
1 : 20
1 : 30
2 : 10   -> key만 정렬됨.

 

첨자 연산자([ ])의 사용 불가능

  • map과는 다르게 첨자([ ]) 연산자를 사용해서 원소를 추가 또는 수정이 불가능하다.
mm[1] = "bc";    // 사용 불가능

 

키(Key)의 중복과 무관하게 요소 삽입 가능

  • 키(Key)의 중복 여부와 상관 없이 insert() 함수를 사용할 수 있다.
auto result = mm.insert({ 1, "100" });
cout << result->first << " : " << result->second << endl;
1 : 100

 

동일한 키의 여러 값들을 한번에 출력하기

  • 동일한 키의 여러 값들을 한꺼번에 출력하기 위해 다음과 같이 다양한 함수를 사용할 수 있다.
    • lower_bound([Key])
    • upper_bound([Key])
    • equal_range(6);

lower_bound(), upper_bound(), equal_range() 함수의 사용 예

 

방법 1 : lower_bound([Key]), upper_bound([Key]) 함수 사용하기

  • lower_bound([Key]), upper_bound([Key]) 함수를 사용한다.
    • lower_bound([Key]) 함수는 키(Key) 값에 해당하는 맨 첫번째 원소를 가리키는 반복자를 반환한다.
      • 개구간 "["으로 사용된다.
    • upper_bound([Key]) 함수는 키(Key) 값에 해당되는 맨 마지막 원소의 다음을 가리키는 반복자를 반환한다.
      • 폐구간 ")" 으로 사용된다.
auto lower = mm.lower_bound(1);     // 처음 위치, key : 1
auto upper = mm.upper_bound(1);     // 다음 위치, key : 2

for (auto i = lower; i != upper; i++) {
    cout << i->first << " : " << i->second << endl;
}
1 : 30
1 : 20
1 : 30

 

방법 2 : equal_range([Key]) 함수 사용하기

  • equal_range([Key]) 함수를 사용한다.
    • equal_range([Key]) 함수는 키(Key) 값에 해당하는 원소의 범위(Range)pair 객체로 반환한다. 
      • pair 객체의 first는 키(Key) 값에 해당하는 원소의 첫번째 반복자를 반환한다. (lower_bound)
      • pair 객체의 second는 키(Key) 값에 해당하는 원소의 마지막 원소의 다음 반복자를 반환한다. (upper_bound)
      • 따라서 [first, second)인 객체를 반환한다고 할 수 있다.
auto range = mm.equal_range(1);
auto lower = range.first;
auto upper = range.second;

for (auto i = lower; i != upper; i++) {
    cout << i->first << " : " << i->second << endl;
}
1 : 30
1 : 20
1 : 30

 

방법 3 : 구조적 바인딩과 equal_range([Key]) 함수 사용하기

  • 구조적 바인딩(Structured Bindings)과 equal_range([Key]) 함수를 사용한다.
  • 구조적 바인딩은 C++17부터 도입된 기능이므로, 이 방법은 C++17부터 사용 가능하다.
auto [lower, upper] = mm.equal_range(1);

for (auto i = lower; i != upper; i++) {
    cout << i->first << " : " << i->second << endl;
}
1 : 30
1 : 20
1 : 30

 

사용 예

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

multimap<int, string> mm1 {
    {2, "10"},
    {1, "30"},
    {1, "20"},
    {1, "30"}
};

multimap<int, string> mm2;

int main() {
    // 요소 출력
    for (const auto& [key, value] : mm1) {
        cout << key << " : " << value << endl;
    }
    
    cout << endl;

    // 요소 삽입
    mm2.insert({1, "100"});
    mm2.insert({1, "70"});
    mm2.insert({1, "20"});
    mm2.insert({1, "60"});
    mm2.insert({2, "45"});
    mm2.insert({2, "70"});
    mm2.insert({3, "20"});
    mm2.insert({4, "75"});
    mm2.insert({5, "90"});
    
    for (const auto& [key, value] : mm2) {
        cout << key << " : " << value << endl;
    }
    
    cout << endl;
    
    // 중복인 요소 출력
    //// 방법 1
    auto lower1 = mm1.lower_bound(1);    
    auto upper1 = mm1.upper_bound(1);   

    for (auto i = lower1; i != upper1; i++) {
        cout << i->first << " : " << i->second << '\n';
    }
    
    cout << endl;
    
    //// 방법 2
    auto range = mm2.equal_range(2);
    auto lower2 = range.first;
    auto upper2 = range.second;
    
    for (auto i = lower2; i != upper2; i++) {
        cout << i->first << " : " << i->second << '\n';
    }
    
    return 0;
}
1 : 30
1 : 20
1 : 30
2 : 10

1 : 100
1 : 70
1 : 20
1 : 60
2 : 45
2 : 70
3 : 20
4 : 75
5 : 90

1 : 30
1 : 20
1 : 30

2 : 45
2 : 70
728x90
728x90