STL, 컨테이너, vector, map, 알고리즘, sort, find, 반복자, begin/end, rbegin/rend range-based for, const auto&, distance, base(), SOLID, 인터페이스
vector: 동적 배열, 끝에 넣고 빼는 건 빠름 / 중간 erase는 비쌈map: 키-값 저장, 키 기준 자동 정렬, 중복 키 불가pair.first, pair.second, insertfor(int num: vec)const auto&: 읽기 전용 + 타입 자동 추론 + 복사 없이 참조sort(시작반복자,끝반복자,비교함수)find(): 찾으면 반복자 반환, 못 찾으면 end()Standard Template Library#include <vector>
vector<int> vec1; //빈 벡터. 크기 0.
vector<int> vec2(5,10); //크기 5, 모든 원소 10으로 초기화
vector<int> vec3(vec2); //vec2 복붙하기
vector<int> vec3 = {1, 2, 3, 4, 5};vector<int> vec2D(3, vector<int>(4, 7));push_back: 벡터의 맨 끝에 원소를 추가하는 메서드vec.push_back(10); 이런 식으로 쓴다.for(int num: vec) //num: vec 원소들 하나하나씩 꺼내오는
//C++ 전용 "range-based for문"
//for(int i=0, i<vec.size()...int num=vec[i] 이런 걸 축약한 느낌
{
std::cout << num <<" ";
}
pop_back: 벡터 맨 끝의 원소를 제거. 크기 자동으로 줄어듦.vec.pop_back() 이런 식으로 쓺. 원소 명시 필요 X.size 벡터의 크기를 확인하는 메서드vec_size()erase: 특정 위치의 원소 제거. 시간 복잡도 커서 엔간하면 사용 안하는 게 맞다.vec.erase(vec.begin()+1) = 두번째 원소 제거vec.erase(vec.begin()+1, vec.begin()+3) = 2~3번째 원소 제거: 끝쪽 위치는 제외erase 를 너무 많이 쓴다? 내가 컨테이너 잘못 골랐을 가능성 높다.pair<const Key, value> 형태로 저장#include <iostream>
#include <map>
//#include <string> -> 없어도 위에 헤더들 때매 돌아갈 순 있는데
//엔간하면 추가하는 게 나음
map<int,string> studentMap; //맵 선언
//키는 정수, 값은 string
//요소 추가하는 방법은
studentMap[101] = "Alice"; //키는 101, 값은 Alice
studentMap[102] = "Bob";
studentMap[103] = "Charlie";
//출력은
for(const auto& pair: studentMap)
{
std::cout <<"ID: " << pair.first <<", Name: " <<pair.second<<std::endl;
}
const auto&: 읽기 전용으로(const) 타입은 컴파일러가 알아서(auto) 참조로 받아서(&) 복사 안하고 효율적으로 값 불러오기 (변수명 pair)for(.....: studentMap): C++ range-based for문이다. 즉 studentMap의 모든 요소를 꺼내서 하나하나 돌리는 for문map은 key 순으로 오름차순 정렬
myMap[20] = "Banana" 식으로 원소 하나 넣으면 알아서 int 키 순으로 정렬해 줌
insert() 를 이용해서 추가 가능
- insert() - make_pair() 이용
myMap.insert(make_pair(1, "Apple"));
- myMap.insert({4, "Dog"}); 식으로도 가능: 앞 값이 key, 뒤가 값
- myMap[7] = "Giraffe"; 도 가능: [] 안에 key
find()
map 에 존재하는지 확인 가능. 존재하면 해당 키의 iterator 반환, 존재하지 않으면 map.end()를 반환int key=2, auto it = myMap.find(key);if (it != myMap.end()) {
cout << "Found! Key: " << it->first << ", Value: " << it->second << endl;
} else {
cout << "Key " << key << " not found!" << endl;
}
size(): 맵의 키-값 쌍의 갯수 반환
erase(): 특정 key 가진 요소 삭제
clear(): 모든 원소 삭제. 대부분의 컨테이너가 가지고 있는 메소드다
myMap.clear();int, double 등) 은 사용자 정렬 함수가 없으면 오름차순으로 정렬 comp(a, b): 첫 번째 인자 a가 앞에 있는 원소를 의미comp(a, b)의 반환타입은 bool.true면 순서 그대로 유지. false 면 a, b 순서 바꿈sort(arr, arr + size); (size=sizeof(arr)/sizeof(arr[0]))comp(a, b) 이거 그냥 bool 문이다 -> comp 여도 되고 compare 여도 되고...왜 뭐 특별한거처럼 써놨지?sort() 사용법: sort(시작 반복자, 끝 반복자, 비교함수)vec.begin() 일 수도 있고, 배열의 경우 그냥 arr 일 수 도 있고...vec.end() 나 arr+sizebool 값 반환해 주는 함수면 뭐든 상관없음. comp 일 필요 Xstring name, int age 멤버변수 가지고 있다고 생각.bool compareByAgeAndName(const Person& a, const Person& b) {
if (a.getAge() == b.getAge()) {
return a.getName() < b.getName(); // 이름 오름차순
}
else
{
return a.getAge() < b.getAge();
} // 나이 오름차순
}
find(first, last, 찾을 값)last 반환last 직전까지 -> 그래서 vec.end() 그냥 넣어도 됨begin() -> 첫 번째 원소.end() 마지막 원소 다음을 가리킴.rbegin() -> 마지막 원소rend() -> 첫 번째 원소 이전을 가리킴.auto it = numbers.begin() 하고 *it 하면 it 주소의 값 불러올 수 있다 Like 포인터it->first 식으로. 클래스 포인터다distance(a, b) -> a원소부터 b 원소까지 거리. b가 begin()면 index 겠지?it.base() 하면 역방향으로 서치 중일때 해당 역방향 반복자 에서 앞의 값을 불러와 준다. why? 반복자는 메모리 '칸' 이 아니라 '칸막이' 를 가리키는 것에 가깝기 때문.distance(words.begin(), it.base()) - 1 이따구로 만들어야 함. 왜 설명을 제대로 못할까?class Car 가 멤버변수로 engine: Engine 을 그냥 받아오는 경우: 디젤엔진, 전기엔진 등등...에 대해 다 별개로 지정을 해줘야함engine: unique_ptr<engine> 으로 받아오기. 자손 클래스로 업캐스팅