맵 (std::map)

맵(map)은 연관 컨테이너(Associative Container) 중 하나이다.

map 은 노드 기반으로 이루어진 균형 이진 탐색 트리 구조이다. (레드-블랙 트리 알고리즘)

mapkeyvalue 로 이루어져 있따. keyvaluepair 객체 형태로 저장되며, key 는 고유한 값이므로 중복이 허용되지 않는다.

map 은 원소가 삽입되면서 key 값을 기준으로 자동으로 오름차순(기본값)으로 정렬된다.

map 은 저장 공간의 필요에 따라 동적할당을 한다.

Untitled


map 의 사용

#include <map>
std::map<KeyType, ValueType> MapName;
std::map<int, int> m; 비어있는 맵 m을 생성
std::map<int, int> m2(m1); 맵 m1을 복사하여 맵 m2를 생성
std::map<int, int, predicate> m; predicate를 통해 정렬 기준을 세운 맵 m을 생성
std::map<int, int, std::greater<int>> m; // 내림차순으로 정렬하는 맵 m을 생성

map 의 멤버 함수

std::map<int, int> m;

m.begin() 첫 번째 원소를 가리키는 iterator를 반환
m.end() 마지막 원소의 다음을 가리키는 iterator를 반환
m.rbegin() 마지막 원소를 가리키는 reverse_iterator를 반환
m.rend() 첫 번째 원소의 앞을 가리키는 reverse_iterator를반환
m.insert(p) pair 객체 p를 삽입함. 삽입 시 자동으로 정렬되며
삽입 성공/실패 여부 pair<iterator, bool>를 반환
m.insert(iter, p) iter가 가리키는 위치부터 pair 객체 p를 삽입할 위치를 탐색해 삽입
m.erase(k) k 값과 key 값이 일치하는 원소를 삭제한 후 제거된 요소의 개수를 반환
m.erase(iter) iter가 가리키는 원소를 삭제한 후 삭제된 원소의 다음 원소를
가리키는 iterator 를 반환
m.erase(start, end) start 반복자부터 end 반복자 전까지 [start, end) 원소를 제거
m.clear() 맵의 모든 원소를 제거
m.find(k) k 값과 key 값이 일치하는 원소를 가리키는 반복자를 반환
만족하는 원소가 없다면 m.end()와 같은 반복자를 반환
m.count(k) k 값과 key 값이 일치하는 원소의 개수를 반환
m.empty() 맵이 비어있으면 true 를 반환
m.size() 원소의 개수를 반환
m.contains(k) 맵에 k 값과 일치하는 key 값이 있으면 true 를 반환 (C++20)
m2.swap(m1) m1 맵과 m2 맵을 서로 바꿈

map 의 원소 삽입

insert()operator[] 를 통해 map 에 원소를 삽입할 수 있다.

#include <iostream>
#include <map>

int main()
{
	std::map<int, std::string> m;
	std::map<int, std::string>::iterator it;

	// operator [] 이용
	m[50] = "user1";
	m[42] = "user2";
	m[52] = "user3";
	m[72] = "user4";

	// insert() 이용
	m.insert({ 57, "user5" });
	m.insert(std::make_pair(20, "user6"));
	m.insert(std::pair<int, std::string>(47, "user7"));

	std::cout << "원소 추가" << std::endl;
	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << it->first << ", " << it->second << "] ";
	}

	// insert는 동일한 key 값이 있으면 기존 원소를 수정하지 않습니다.
	m.insert({ 50, "user8" });

	// operator [] 는 동일한 key 값이 있으면 기존 원소를 수정합니다.
	m[20] = "user9";

	std::cout << "\\n\\n원소 수정" << std::endl;
	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << (*it).first << ", " << (*it).second << "] ";
	}

	// (추가) insert는 원소 삽입 성공 여부를 반환합니다.
	std::pair<std::map<int, std::string>::iterator, bool> isInsert;

	std::cout << std::endl << std::boolalpha;
	isInsert = m.insert({ 80, "user10" }); // 새로운 key 값이므로 삽입 됨
	std::cout << "\\n원소 삽입 : " << isInsert.second;
	isInsert = m.insert({ 42, "user11" }); // 이미 있는 key 값이므로 삽입 되지 않음
	std::cout << "\\n원소 삽입 : " << isInsert.second;

	std::cout << "\\n\\n 원소 삽입 후"<< std::endl;
	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << (*it).first << ", " << (*it).second << "] ";
	}

	return 0;
}
원소 추가
[20, user6] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4]

원소 수정
[20, user9] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4]

원소 삽입 : true
원소 삽입 : false

 원소 삽입 후
[20, user9] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4] [80, user10]

map 의 원소 삭제

erase()clear() 를 통해 map 의 원소를 삭제 할 수 있다.

#include <iostream>
#include <map>

int main()
{
	std::map<int, std::string> m;
	std::map<int, std::string>::iterator it;

	m[50] = "user1";
	m[42] = "user2";
	m[52] = "user3";
	m[72] = "user4";
	m[57] = "user5";
	m[20] = "user6";
	m[47] = "user7";

	std::cout << "원소 삭제 전" << std::endl;
	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << it->first << ", " << it->second << "] ";
	}

	// key 값을 기준으로 원소 삭제
	std::cout << "\\n\\n원소 삭제(key)" << std::endl;

	int key = 72;
	std::cout << "삭제할 원소 : " << key << std::endl;
	size_t count = m.erase(key); // 제거된 요소의 개수를 반환
	std::cout << "삭제된 원소의 수 : " << count << std::endl;

	// iterator 를 이용해 원소 삭제
	std::cout << "\\n원소 삭제(iter)" << std::endl;
	
	std::map<int, std::string>::iterator erase_it;
	it = m.begin();
	std::cout << "삭제할 원소 : " << it->first << std::endl;
	erase_it = m.erase(it);
	std::cout << "반환된 (iter) : " << erase_it->first << std::endl;

	std::cout << "\\n원소 삭제 후" << std::endl;
	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << it->first << ", " << it->second << "] ";
	}

	// clear()를 이용해 전체 원소 삭제
	m.clear();

	std::cout << "\\n\\n맵 clear 후" << std::endl;
	if (m.empty())
		std::cout << "map이 비었습니다.";
	else
		std::cout << "map이 비어있지 않습니다.";

	return 0;
}
원소 삭제 전
[20, user6] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4]

원소 삭제(key)
삭제할 원소 : 72
삭제된 원소의 수 : 1

원소 삭제(iter)
삭제할 원소 : 20
반환된 (iter) : 42

원소 삭제 후
[42, user2] [47, user7] [50, user1] [52, user3] [57, user5]

맵 clear 후
map이 비었습니다.

map 사용 예시

find

#include <iostream>
#include <map>

int main()
{
	std::map<int, std::string> m;
	std::map<int, std::string>::iterator it;

	m[50] = "user1";
	m[42] = "user2";
	m[52] = "user3";
	m[72] = "user4";
	m[57] = "user5";
	m[20] = "user6";
	m[47] = "user7";

	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << it->first << ", " << it->second << "] ";
	}

	// find() 를 이용해 원하는 원소를 찾을 수 있습니다.
	int key = 52;
	std::cout << "\\n\\n찾으려는 원소 : " << key << std::endl;
	it = m.find(key);
	std::cout << "[" << it->first << ", " << it->second << "]";

	// 만약 일치하는 key 값이 없다면 end()를 가리키는 반복자를 반환합니다.
	key = 40;
	std::cout << "\\n\\n찾으려는 원소 : " << key << std::endl;
	it = m.find(key);

	if (it != m.end())
		std::cout << "원소 발견!" << std::endl;
	else
		std::cout << "원소 미발견..." << std::endl;

	return 0;
}
[20, user6] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4]

찾으려는 원소 : 52
[52, user3]

찾으려는 원소 : 40
원소 미발견...

contains

C++20 버전 부터 사용할 수 있다.

#include <iostream>
#include <map>

int main()
{
	std::map<int, std::string> m;
	std::map<int, std::string>::iterator it;

	m[50] = "user1";
	m[42] = "user2";
	m[52] = "user3";
	m[72] = "user4";
	m[57] = "user5";
	m[20] = "user6";
	m[47] = "user7";

	for (it = m.begin(); it != m.end(); ++it)
	{
		std::cout << "[" << it->first << ", " << it->second << "] ";
	}

	// contains() 원소의 존재 여부를 알 수 있다.
	int key = 52;
	std::cout << "\\n\\n찾으려는 원소 : " << key << std::endl;
	if (true == m.contains(key))
	{
		std::cout << "맵에 원소가 있습니다." << std::endl;
	}
	else
	{
		std::cout << "맵에 원소가 없습니다." << std::endl;
	}

	key = 55;
	std::cout << "\\n찾으려는 원소 : " << key << std::endl;
	if (true == m.contains(key))
	{
		std::cout << "맵에 원소가 있습니다." << std::endl;
	}
	else
	{
		std::cout << "맵에 원소가 없습니다." << std::endl;
	}

	return 0;
}
[20, user6] [42, user2] [47, user7] [50, user1] [52, user3] [57, user5] [72, user4]

찾으려는 원소 : 52
맵에 원소가 있습니다.

찾으려는 원소 : 55
맵에 원소가 없습니다.