- Stack
- Queue
- Deque
- Segment Tree
- 소수
- (중복)순열과 (중복)조합
- modulo 연산의 사칙연산
- GCD & LCM
- CCW
- 다각형 내부의 점 1688
- DFS & BFS
- Union Find
- MST: Minimum Spanning Tree
- LIS
- Topological Sort
auto
는 C++11에서 처음 등장하여 C++11 이후로 사용 가능
for (auto a : arr) // 인자를 복사. 복사 비용 발생. 원래 값 변경 불가. 읽기만 할 것이라면 좋지 못함.
for (auto& a : arr) // &를 통해 복사가 아닌 reference를 가져오지 않음. 복사 비용 X. 원래 값 변경 가능.
for (const auto& a : arr) // &를 통해 복사가 아닌 reference를 가져오지 않음. 복사 비용 X. 원래 값 변경 불가.
🌸 #include <map>
map<string, int> m;
이라고 가정
-
순회
-
while-loop 및 전통적인 for문
auto iter = m.begin(); // type of m is map<string, int>::iterator while (iter != m.end()) { cout << "key: " << iter->first << ' ' << ", value: " << iter->second << endl; iter++; }
for (auto iter = m.begin(); iter != m.end(); iter++) { cout << "key: " << iter->first << ' ' << ", value: " << iter->second << endl; }
-
range based for statement
C++11에 range based for statement(범위 기반 for문)가 추가되었다. 이를 이용해서 보다 간단하게 map을 순회할 수 있다.
for (const auto& item : m) { cout << "key: " << item.first << ' ' << ", value: " << item.second << endl; }
-
range based for statement 2
이 방법은 C++17 이후에서 지원된다.
for (const auto& [key, value] : m) { cout << "key: " << key << ' ' << ", value: " << value << endl; }
-
-
키 검색 Time Complexity:
O(log n)
맵에서 키를 검색하여 키가 존재하면 iterator를 반환하고, 존재하지 않으면
map.end()
를 반환한다.auto item = m.find("keyword"); item != m.end() ? cout << "key exist.\n" : cout << "key does not exist.\n";
auto item = m.find("keyword"); if (item != m.end()) { cout << "key: " << item->first << ' ' << ", value: " << item->second << endl; }
🌸 #include <set>
중복을 허용하지 않으며 원소가 정렬된다. (default: 오름차순)
균형 이진 트리로 구현되어 있기 때문에 탐색 시간이 평균, 최악 모두 O(log n)
이다.
set<string> s;
라고 가정
-
순회
-
전통적인 for문
for (auto iter = s.begin(); iter != s.end(); iter++) { cout << *iter << ' '; } cout << endl;
-
range based for statement
for (const auto& elem : s) { cout << elem << ' '; } cout << endl;
-
-
원소 검색
Time Complexity:O(log n)
set에서 원소를 검색하여 원소가 존재하면 iterator를 반환하고, 존재하지 않으면
set.end()
를 반환한다.auto item = s.find("word"); item != s.end() ? cout << "element exist.\n" : cout << "element does not exist.\n";
auto item = s.find("word"); if (item != s.end()) { cout << "element: " << *item << endl; }
🌸 #include <unordered_set>
중복을 허용하지 않으며 원소가 정렬되지 않는다.
원소 삽입과 검색 시 해시 함수를 사용한다. (해시 테이블 기반 저장)
따라서 탐색 시간이 평균 O(1)
이지만, 최악의 경우 O(n)
이다.
해시 충돌이 많이 발생하게 되면 성능이 나빠진다.
🌸 #include <queue>
-
생성
priority_queue<int> pq; // Max Heap으로 priority_queue<int, vector<int>, less<int>> pq;와 같음. priority_queue<int, vector<int>, greater<int>> pq; // Min Heap
-
사용자 정의
영어 점수(eng)가 높은 학생이 top을 유지하도록 만들기. 단, 영어 점수가 같다면 수학 점수(mat)가 높은 학생이 top이 되도록struct Student { string id, name; int mat, eng; Student(string ID, string NAME, int MAT, int ENG) : id(ID), name(NAME), mat(MAT), eng(ENG) {} bool operator<(const Student& stu) const { if (eng == stu.eng) return mat < stu.mat; return eng < stu.eng; } }; priority_queue<Student> pq;
struct Student { string id, name; int mat, eng; Student(string ID, string NAME, int MAT, int ENG) : id(ID), name(NAME), mat(MAT), eng(ENG) {} }; struct comp { bool operator()(const Student& stu1, const Student& stu2) { if (stu1.eng == stu2.eng) return stu1.mat < stu2.mat; return stu1.eng < stu2.eng; } }; priority_queue<Student, vector<Student>, comp> pq;
🌸 #include <string>
string str = "hello world!";
-
관련 함수
-
str.find()
- 찾기문자열에서 원하는 문자 또는 문자열의 위치를 찾는다.
return 값: 문자열을 찾았으면 해당 문자열의 시작 위치를 반환, 찾지 못했으면 string::npos를 반환-
str.find("찾을 문자열")
- str의 처음부터 찾을 문자열을 찾음ex.
str.find("hello")
->0
str.find("world")
->6
str.find('l')
->2
-
str.find("찾을 문자열", 검색 시작 위치)
- str[검색 시작 위치]부터 찾을 문자열을 찾음ex.
str.find('l', 2);
->2
str.find('l', 4);
->9
-
-
str.substr()
: 문자열 자르기문자열의 일부를 반환한다.
원래 문자열의 [idx, idx + count)까지의 문자열을 반환하며, idx가 원래 문자열의 길이보다 길면 out_of_range 예외를 발생시킨다.
idx + count가 원래 문자열의 길이보다 길면 원래 문자열의 끝까지를 반환한다.-
str.substr(자를 시작 인덱스)
- 자를 시작 인덱스부터 문자열의 끝까지 반환ex.
str.substr(4)
->o world!
str.substr(6)
->world!
-
str.substr(자를 시작 인덱스, 개수)
- 자를 시작 인덱스부터 개수만큼 문자열을 반환ex.
str.substr(5, 3)
->wo
str.substr(0, 5)
->hello
str.substr(1, 100)
->ello world!
-
-
-
특정 문자 기준으로 자르기
int sep = str.find("특정 문자"); int prev = 0; while (sep != string::npos) { string sub = str.substr(prev, sep - prev); v.push_back(sub); // 문자열이 정수인 경우: v.push_back(stoi(sub)); prev = sep + 1; sep = str.find("특정 문자", prev); } v.push_back(str.substr(prev)); // 문자열이 정수인 경우: v.push_back(stoi(str.substr(prev)));
🌸 #include <algorithm>
for-loop 대신 복사할 수 있는 방법
copy(복사할 메모리의 시작을 가리키는 포인터, 복사할 메모리의 마지막을 가리키는 포인터, 복사 받을 메모리의 시작을 가리키는 포인터);
const int SIZE = 50;
int arr1[100], arr2[SIZE], arr3[100][100], arr4[SIZE][SIZE];
int copy1[100], copy2[SIZE], copy3[100][100], copy4[SIZE][SIZE];
// 1차원 배열 복사
copy(arr1, arr1 + 100, copy1);
copy(arr2, arr2 + SIZE, copy2);
// 2차원 배열 복사
copy(&arr3[0][0], &arr3[0][0] + (100 * 100), ©3[0][0]);
copy(&arr4[0][0], &arr4[0][0] + (SIZE * SIZE), ©4[0][0]);
// 벡터
v1.resize(SIZE); // 1차원
v1.resize(SIZE, vector<int>(SIZE)); // 2차원
copy(v.begin(), v.end(), copyv.begin()); // 복사는 1차원 벡터 2차원 벡터 동일