[C++] STL map vs multimap (feat. multimap equal_range)

반응형
반응형

* 다음 포스팅은 STL map 컨테이너와  multimap 컨테이너의 차이점에 대해 다루고 있습니다. 

map 혹은 multimap 컨테이너의 사용법에 대한 정보를 원하시는 분들은 다음 포스팅을 참고해 주세요.

→ [C++] STL map Container 사용 방법 정리

 

* 개인적인 공부 내용을 기록하는 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있으며,

지속적으로 수정해 나갈 예정입니다.


_Contents

#1 Key값의 중복

#2 [] 연산자

#3 equal_range


 

C++ STL 표준 라이브러리에는 map 과 multimap 컨테이너를 제공합니다.

map과 multimap 컨테이너의 사용방법은 거의 동일하지만 몇 가지 차이점이 존재합니다.

 

#1 Key값의 중복

- map 컨테이너는 키값의 중복을 허용하지 않는다. 

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

int main(){
	// map container - key값 중복 허용 x
	map<int, string> myMap;
	myMap.insert(make_pair(1, "nov"));
	myMap.insert(make_pair(1, "novv"));
	myMap.insert(make_pair(2, "novvv"));
	cout << "[Print myMap]" << '\n';
	for(const auto& i : myMap){
		cout << "key : " << i.first << " value : " << i.second << '\n';
	}
    return 0;
}

map 컨테이너는 키값의 중복을 허용하지 않습니다. 

위 코드를 실행시켜 보시면 중복된 두 번째 키 (1, "novv") 의 입력을 무시합니다.

[Print myMap]
key : 1 value : nov
key : 2 value : novvv

 

 

- multimap 컨테이너는 키값의 중복을 허용한다.

	multimap<int, string> myMultimap;
	myMultimap.insert(make_pair(1, "nov"));
	myMultimap.insert(make_pair(1, "novv"));
	myMultimap.insert(make_pair(2, "novvv"));
	cout << "[Print myMultimap]" << '\n';
	for(const auto& i : myMultimap){
		cout << "key : " << i.first << " value : " << i.second << '\n';
	}

 반면 multimap 컨테이너는 Key값의 중복을 허용합니다.

(1, "novv") 키를 중복처리해 삭제시킨 map 컨테이너와 달리 multimap 컨테이너는 키값이 중복으로 입력되어도, Key - Value 쌍을 제거하지 않습니다. 

[Print myMultimap]
key : 1 value : nov
key : 1 value : novv
key : 2 value : novvv

#2 [] 연산자 

- map 컨테이너는 [] 연산자를 사용해 키값에 접근할 수 있다.

map 컨테이너는 다음과 같이 [] 연산자를 사용하여 키에 접근하여 Value를 출력할 수 있습니다.

	// Access to Key 1
	cout << "Key 1 -> " << myMap[1] << '\n';
Key 1 -> nov

 

- multimap 컨테이너는 [] 연산자를 사용해 키값에 접근할 수 없다.

반면 multimap 컨테이너는 [] 연산자를 사용해 키값에 접근하는 것이 불가능합니다. 

이유는 앞에서 설명드린 첫 번째 특성을 떠올려 보시면 당연한데, 애초에 multimap 컨테이너는 키값의 중복을 허용하기에 중복되는 키값중 어떤 키에 접근할 지 판별하는 것이 불가능하기 때문입니다.


#3 equal_range

multimap 컨테이너에 find member function을 사용해 중복된 키값에 접근해 보도록 하겠습니다. 

	multimap<int, string>::iterator it = myMultimap.find(1);
	if(it != myMultimap.end()){
		cout << "Key 1 -> " << it->second << '\n';
	}
	else{
		cout << "myMultimap 컨테이너에 해당하는 원소가 존재하지 않습니다.";
	}

 

중복된 키값들 중 가장 첫 번째 키에 접근하여 "nov"를 출력했습니다.

하지만 C++은 중복된 키에 대해 find 멤버 함수가 어떻게 접근하는지에 대한 정확한 표준을 제시하지 않습니다.

즉, 컴파일러 환경에 따라 완전히 상이한 랜덤값을 출력할 수 있다는 것 입니다. 

[Print myMultimap]
key : 1 value : nov
key : 1 value : novv
key : 2 value : novvv
Key 1 -> nov

 

따라서 C++은 equal_range member function 을 제공합니다. 

equal_range 함수는 key값에 해당하는 원소의 "범위"를 pair객체 형태로 반환해 줍니다.

정확히는 upper_bound 와 lower_bound를 각각 pair 객의 first, second 로 반환 합니다.

 

upper_bound(key) : key값에 해당하는 맨 마지막 원소의 "다음" 원소를 가리키는 반복자를 return 합니다.

lower_bound(key) : key값에 해당하는 맨 첫 번째 원소를 가리키는 반복자를 return 합니다.

	cout << "[Print myMultimap ... Key1]" << '\n';
	auto range = myMultimap.equal_range(1);
	for(auto iter = range.first; iter != range.second; ++iter){
		cout << iter->first << " : " << iter->second << " " << '\n';
	}
[Print myMultimap ... Key1]
1 : nov
1 : novv

reference 

https://cplusplus.com/reference/algorithm/equal_range/

반응형

댓글

Designed by JB FACTORY