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
16
17
#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
3
1234
umbum 1234

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

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

1
2
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
5
1 a
2 B
3 C
1 1 1 0

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

1
2
3
4
5
6
7
8
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.