Post

(C++) 맵 - unordered_map (hash_map)

find와 count로 exist 체크

내부에 해당 key가 존재하는지는 count()/find()를 사용한다. 중복을 허용하지 않는 자료구조에서 둘은 내부적으로 거의 똑같기 때문에, 취향 대로 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <unordered_map>

std::unordered_map<std::string, int> hash_map;
int main() {
    hash_map.insert(std::make_pair("umbum", 1234));  // hash_map["umbum"] = 1234 도 가능.
    if (hash_map.count("umbum")) {
        std::cout << hash_map["umbum"] << '\n';
    }

    auto item = hash_map.find("umbum");
    if (item != hash_map.end()) {
        std::cout << item->first << ' ' << item->second << '\n';
    }
}
1
2
1234
umbum 1234

주의! m[5]; 를 쓰는 것 만으로도 m[5]가 생성된다!

1
2
3
std::map<int, string> m;
m[5];    // 또는 printf("%d\n", m[5]);
printf("%d\n", m.count(5));
1
1

m.find(5) 해봐도 해당 키가 있는 것으로 나온다. m[5]하는 순간 맵에 key:value = 5:NULL 이렇게 잡혀버리는 듯. 그래서 해당 키가 있냐 없냐를 따지면 있는 것으로 나옴!

m.insert(make_pair) 보다는 python에서 하듯 m[key]를 사용해라

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
map<int, string> m;
void testMap() {
    m.insert(make_pair(1, "a"));
    m.insert(make_pair(2, "b"));
    m.insert(make_pair(1, "A"));    // m[1]은 A가 될 것 같지만, 변경되지 않는다.
    m[2] = "B";    // 이렇게 하면 m[2]는 B로 변경된다.
    m[3] = "C";
}

int main(void) {
    testMap();
    for (auto item = m.begin(); item != m.end(); item++) {
        cout << item->first << " " << item->second << endl;
    }
    printf("%d %d %d %d\n", m.count(1), m.count(2), m.count(3), m.count(4));
    return 0;
}
1
2
3
4
1 a
2 B
3 C
1 1 1 0

이미 있는 키에 insert를 하면 변하지 않는다. 이게 꽤 직관과는 다르게 동작하는 부분이라, m[key] 접근을 사용하는게 좋아보인다. 객체를 value로 쓰는 경우, 생성자 두개가 모두 있어야 한다.

1
2
3
4
5
6
7
class T {
public:
    int i;
    T() {}
    T(int _i): i(_i) {}
};
m[2] = T(2);
This post is licensed under CC BY 4.0 by the author.