728x90

 

1. map

 

정의
  • 고유한 키를 기반으로 키 - 값 (key-value) 으로 이루어져 있는 정렬된(삽입할 때마다 자동 정렬) 연관 컨테이너 
  • 레드 - 블랙트리로 구현
    • 균형 이진 검색 트리 

 

시간복잡도
  • 레드 - 블랙트리로 구현되어 있어서
  • 삽입, 삭제, 수정, 탐색 -> O(logN) 

 

특징
  • 고유한 키를 갖기 때문에 하나의 키에 중복된 값 xxx
  • 자동으로 오름차순 정렬되기 때문에 넣은 순서대로 map을 탐색하는 것이 아닌 아스키코드순으로 정렬된 값들을 기반으로 탐색 
  • 대괄호 연산자 [] 로 해당 키로 직접 참조 가능
  • 키와 value는 string이나 int 뿐만 아니라 다양한 값이 가능
  • iterator로 순회 가능

 

예시 코드
#include <bits/stdc++.h>
using namespace std;
map<string, int> mp;
string a[] = {"천", "현", "태"};
int main(){
    for(int i = 0; i < 3; i++){
        mp.insert({a[i], i + 1});
        mp[a[i]] = i + 1;
    }
    // mp에 해당 키가 없다면 0으로 초기화 되어 할당됨.(int의 경우)
    // 만약 mp에 해당 키가 없는지 확인하고 싶고
    // 초깃값으로 0으로 할당되지 않아야 되는 상황이라면
    // find를 써야 함.
    cout << mp["hyeontae"] << '\n';
    // 대괄호로 수정가능
    mp["hyeontae"] = 4;
    cout << mp.size() << '\n';
    mp.erase("hyeontae");
    
    auto it = mp.find("hyeontae");
    if(it == mp.end()){
        cout << "존재하지 않음\n";
    }
    mp["hyeontae"] = 100;
    
    it = mp.find("hyeontae");
    if(it != mp.end()){
        cout << (*it).first << " : " << (*it).second << '\n';
    }
    for(auto it : mp){
    	cout << (it).first << " : " << (it).second << '\n';
    }
    for(auto it = mp.begin(); it != mp.end(); it++){
    	cout << (*it).first << " : " << (*it).second << '\n';
    }
    mp.clear();
    return 0;
}

/*
0
4
존재하지 않음
hyeontae : 100
hyeontae : 100
천 : 1
태 : 3
현 : 2
hyeontae : 100
천 : 1
태 : 3
현 : 2
*/

 

method

 

  • insert({key : value})
    • map에다 {key, value}를 집어 넣는다.
  • [key] = value
    • 대괄호[]를 통해 key에 해당하는 value를 할당
  • [key]
    • 대괄호[]를 통해 key를 기반으로 map에 있는 요소 참조
    • 만약 map에 해당 키에 해당하는 요소가 없다면 0 또는 빈문자열로 초기화가 되어 할당
    • 할당되고 싶지 않아도 대괄호[]로 참조할 경우 자동으로 할당되기 때문에 조심
  • size()
    • map에 있는 요소들의 개수 반환
  • erase(key)
    • 해당 키에 해당하는 요소를 지운다.
  • find(key)
    • map에서 해당 key를 가진 요소를 찾아 해당 이터레이터를 반환
    • 만약 못찾을 경우 mp.end() -> 해당 map의 end() 이터레이터를 반환
  • clear()
    • map에 있는 요소 다 제거

 

주의할 점
  • 아래 코드처럼 map의 경우 해당 인덱스에 참조만 해도 맵에 값이 생기며 맵의 요소가 생긴다.
  • int 형 같은 경우 0, string 또는 char의 경우 빈 문자열
#include <bits/stdc++.h>
using namespace std;
map<int, int> mp;
map<string, string> mp2;
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cout << mp[1] << '\n';
    cout << mp2["aaa"] << '\n';
    for(auto i : mp) cout << i.first << " " << i.second;
    cout << '\n';
    for(auto i : mp2) cout << i.first << " " << i.second;
    return 0;
}
/*
0

1 0
aaa 
*/

 

따라서, 아래 코드처럼 "맵에 요소가 있는지 없는지"를 확인하고 맵에 데이터를 할당하는 부분의 로직을 구축할 수 있다.

#include <bits/stdc++.h>
using namespace std;
map<int, int> mp;
map<string, string> mp2;
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    if(mp[1] == 0){
        mp[1] = 2;
    }
    for(auto i : mp) cout << i.first << " " << i.second;
    
    return 0;
}

/*
1 2
*/

 

  • 다만 위의 코드는 문제에서 해당 키값에 0이 아닌 값이 들어갈 때 활용 가능
  • 만약 문제에서 키에 0이 들어가는 경우 위 코드는 활용 불가능
  • 이미 if문 안에 mp[1] == 0 을 해버린 순간 이미 mp[1] = 0이 할당되어버리기 때문

 

만약 문제에서 맵의 키 - 값에서 값에 0이 들어가는 경우 아래 코드를 쓰는게 좋다.

또한 이런걸 비교하기 귀찮다면 아래 코드 기반 작성하면 된다.

 

#include <bits/stdc++.h>
using namespace std;
map<int, int> mp;
map<string, string> mp2;
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL(;
    if(mp.find(1) == mp.end()){
        mp[1] = 2;
    }
    for(auto i : mp) cout << i.first << " " << i.second;
    
    return 0;
}

/*
1 2
*/

 


2. unordered_map

  • 앞서 본 map의 경우 자동 정렬
  • unordered_map은 정렬이 되지 않은 map이며
  • method는 동일

 

map과 unordered_map 비교
  • map
    • 정렬이 됨
    • 레드 블랙 트리 기반
    • 탐색, 삽입, 삭제 -> O(logN)
  • unordered_map
    • 정렬이 안됨
    • 해시테이블 기반
    • 탐색, 삽입, 삭제 -> 평균 O(1), 최악 O(N) 

 

예시 코드

 

#include<bits/stdc++.h>
using namespace std;
unordered_map<string, int> umap;
int main(){
    umap["bcd"] = 1;
    umap["aaa"] = 1;
    umap["aba"] = 1;
    for(auto it : umap){
    	cout << it.first << " : " << it.second << '\n';
    }
}
/*
정렬이 되지 않는다.
aba : 1
aaa : 1
bcd : 1
*/

 

  • 정렬이 필요하지 않은 문제에는 unordered_map을 써야할 것 같지만 시간 초과가 나기도 한다
    • 가장 최악의 경우 O(N)이기 때문
    • 그냥 되도록 map을 쓰는 것을 권장
728x90

'Programming Language > C++' 카테고리의 다른 글

[C++] Stack with Cpp  (0) 2023.12.20
[C++] set, multiset with Cpp  (0) 2023.12.20
[C++] list with Cpp  (2) 2023.12.20
[C++] Vector with Cpp  (1) 2023.12.20
[C++] Array with Cpp  (1) 2023.12.20