새로 추가된 STL (unordered_map/set, array, 반복문)
태그: array, C++, Cpp, STL, unordered_map
카테고리: Cpp
🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트
새로 추가된 STL
- std::unordered_map (그리고 unordered_multimap)
- std::unordered_set (그리고 unordered_multiset)
- std::array
기존의 map, set은 이진 트리 기반 컨테이너 였다. O(log N)
정렬을 해야 했기 때문에.
그렇지만 정렬 필요 없고 접근이 빠른(O(1)) 해시맵, 해시셋의 기능을 하는 게 필요했다.
그래서 생겨났다!
1. 정렬 안된 맵 (unordered_map) + 셋(unordered_set)
- std::map은 자동으로 정렬되는 컨테이너
- 그래서 요소 삽입/제거가 빈번할 경우 성능 저하 이슈 우려가 있음
💡 그래서 unordered_map 이 생겨나게 되었다!
- 키와 값의 쌍(pair)들을 저장
- 키는 중복 불가
- 자동으로 정렬되지 않는 컨테이너
- 요소는 해쉬 함수가 생성하는 색인 (index) 기반의 버킷(bucket)으로 구성됨
- 해쉬맵(hashmap)이라고도 함
- (O(1)) 의 속도는 즉 요소가 몇개가 있던 간에 한번에 찾아올 수 있는 속도를 뜻함
- (O(N)) 의 속도는 N개의 요소 중 어떤 값을 찾으려 할 때 for문 한번 돌려야 한다~ 이게 O(N).
정렬 안 된 셋(set) 도 있음요.
정렬 안 된 맵이랑 거의 같다.
2. 어레이 (array)
- std::array
- 전에 만들었던 FixedVector 템플릿 클래스(링크) 와 비슷.
- 그러나 요소 수를 기억하지 않음
- 단순히 c스타일 배열을 추상화 한거다~
- 사이즈 경계 체크는 해줌.
2-1. FixedVector
1
2
3
4
5
6
7
8
9
10
// FixedVector
FixedVector<int, 3> numbers;
numbers.Add(1);
std::cout << numbers.GetSize() << std::endl;
// 하나 넣었으므로 당연히 Size는 1.
std::cout << numbers.GetCapacity() << std::endl;
// 용량이 변하지 않는 FixedVector... 3짜리로 만들었으니 당연히 3.
2-2. std::array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <array>
// ...
std::array<int, 3> numbers;
numbers[0] = 1;
std::cout << numbers.size() << std::endl;
// 3이 출력됨. 지금 어레이에 몇개를 넣었는지 추적하지 않는다.
// 처음 선언할 때 3으로 선언해서 3 나옴.
// FixedVector에서 인덱스 0에 대입한다면, 에러가 날 것. 넣지도 않았으니까...
// 즉, 어레이 3 선언하는 순간 3개 잡아준다는 거다.
std::cout << numbers.max_size() << std::endl;
// 3.
3. 범위 기반 for 반복문
기존의 for 반복문들은…
1
2
3
4
5
6
int scores[3] = { 10, 20, 30 };
for (int i = 0; i < 3; ++i)
{
std::cout << scores[i] << " " << std::endl;
}
이렇게 인덱스 접근을 하거나.
1
2
3
4
5
6
7
8
9
10
std::map<std::string, int> scoreMap;
scoreMap["Lulu"] = 10;
scoreMap["Coco"] = 50;
scoreMap["Mocha"] = 100;
for (auto it = scoreMap.begin(); it != scoreMap.end(); ++it)
{
std::cout << it->first << ": " << it->second << std::endl;
}
이렇게 반복자로 접근해왔었음.
하지만 C#에선 foreach로 좀 더 간편하게 반복문을 돌 수 있음.
그걸 배워옴.
1
2
3
4
5
6
7
8
int scores[3] = { 10, 20, 30 };
// 처음부터 끝까지 각 요소별로 score에 대입하면서 반복을 하라.
// 값으로 복사된다는 것 참고!
for (int score : scores)
{
std::cout << score << " " << std::endl;
}
1
2
3
4
5
6
7
8
9
10
11
std::map<std::string, int> scoreMap;
scoreMap["Lulu"] = 10;
scoreMap["Coco"] = 50;
scoreMap["Mocha"] = 100;
// &... 참조형으로 읽어온다!
for (auto& score : scoreMap)
{
std::cout << it->first << ": " << it->second << std::endl;
}
3-1. for_each()는 어떨까?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
std::unordered_map<std::string, int> scores;
scores["Lulu"] = 70;
scores["Chris"] = 50;
scores["Monica"] = 100;
// 람다
auto printElement = [](std::unordered_map<std::string, int>::value_type& item)
{
std::cout << item.first << ": " << item.second << std::endl;
};
for_each(scores.begin(), scores.end(), printElement);
// 처음부터 끝까지 printElement 함수 실행해줘라.
return 0;
}
- C++03
- 컨테이너의 각 요소마다 함수를 실행하는 알고리듬
- 범위 기반 for만큼 가독성이 높진 않다
댓글남기기