본문 바로가기

프로그래밍/Effective STL

[effective STL] 항목 34 : 정렬된 범위 동작 알고리즘들 기본적으로 정렬된 데이터를 넘겨 동작하는 알고리즘들이 있다는 이야기. binary_search, lower_bound, upper_bound, equal_range: 반드시 정렬된 데이터. 내부적으로 이진 탐색을 사용해 값을 찾는다. set_union, set_intersection, set_difference, set_symmetric_difference: 기본적으로 선형시간으로 동작하지만 정렬하지 않은 데이터는 터무니 없이 느리다. merge, inplace_merge: 두 정렬된 범위를 받아 합치는 알고리즘으로 하나라도 정렬되지 않으면 동작하지 않는다. includes: 어떤 범위 안에 값이 있는지 여부를 알아보는 알고리즘. 정렬되어 있음을 가정하고 동작한다.기본적으로 선형시간이지만 정렬되어 있지 ..
[effective STL] 항목 33 : remove 같은 알고리즘 사용할 때 포인터 컨테이너 주의 동적으로 할당한 객체를 관리하는 컨테이너가 있을 때 주의해야 한다는 것이다. 상황(예시)widget 객체를 동적으로 여러개 선언하고 이를 관리하는 v라는 widget 포인터 백터가 있다고 가정한다. 12345678910111213clss Widget{public: ... bool isCertified() const; ...}; vector v; ...v.push_back(new Widget);...cs widget 객체 중에 certified 되지 않은 위젯을 지우고 싶다! 12v.erase(remove_if(v.begin(), v.end(), not1(mem_fun(&Widget::isCertified))), v.end());cs not1과 mem_fun 함수들을 사용해 본 적은 없는데.. 대충 아닐때..
[effective STL] 항목 32 : 요소 정말로 제거하기 정말 중요한 핵심remove는 어느 것도 "진짜로" 없애지 않는다. 없앨 수 없기 때문이다.책에서 이 문장을 아주 중요하게 두 번이나 반복하고 있다. 님아.. 근데 list는 지워지긴 하잖아욤.... 이건 멤버 함수라 이건가? https://github.com/ElementalKiss/Cpp/blob/master/Example/RealEraseElementInContainerUsingRemoveAndErase.cpp 예시우리가 자주 사용하는 vector를 예로 들면, 1234567 vector intVec; const int VEC_SIZE = 10; intVec.reserve(VEC_SIZE); for (int i = 0; i 00114444??(remove : 2가 삭제되지 컨테이너가 정말 삭제되진 ..
[effective STL] 항목 31 : 정렬시 선택 사항들을 제대로 파악 정리- vector, string, deque, c++ array에 대해 전체 정렬을 수행할 필요가 있을 때는 sort나 stable_sort를 사용한다.- 상위 n개의 요소만 순서에 맞추려면 partial_sort를 사용한다.- 상위 n개의 요소를 뽑되 순서를 고려할 필요가 없다면 nth_element가 적합하다.- 표준 시퀀스 컨테이너가 있고, 이 컨테이너의 요소들을 어떤 기준에 만족하는 것들과그렇지 않은 것들을 모아 구분하고 싶다면 partition이나 stable_partition을 고려해본다.- 사용하고 있는 데이터가 list인 경우엔 partition과 stable_partiton은 직접 사용할 수 있으며sort와 stable_sort 알고리즘 대신에 list:sort 멤버 함수를 사용할 수 ..
[effective STL] 항목 30 : 알고리즘의 데이터 기록 범위는 충분히 크게 잡자. 핵심알고리즘을 쓰기 전에 내부 동작 구조를 알고 컨테이너를 결정해주고,재할당이 최대한 일어나지 않게 범위를 잘 잡아야 한다. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#include #include #include #include #include #include using namespace std; int transmogrify(int x) { return x*x; } template void printVector(T SomeContainer, string str) { cout
[effective STL] 항목 28 : reverse_iterator 쓸 때 base() 잘 쓰기 핵심insert나 erase 사용 시 인자로 결국 iterator를 사용하기 때문에reverse_iterator를 iterator로 변환해주어야한다.이때 insert는 상관 없지만 erase는 대응하는 iterator가 아닐 수 있다. 123456789 vector intVec; const int VECSIZE = 10; intVec.reserve(VECSIZE); for (size_t i = 0; i
[effective STL] 항목 27 : const_iterator -> iterator는 distance와 advance를 사용하자. 핵심(우리가 해서는 안 될 짓)const_iterator와 iterator는 서로 다른 클래스이다.string과 complex의 관게보다도 멀다고 한다.한 마디로 캐스팅이 안 된다. 전혀 엉뚱한 클래스를 캐스팅하려 하지 말자. 해결(const_it -> it)과정1. 컨테이너의 첫 요소를 가리키는 iterator를 생성한다.2. const_iterator가 가리키는 곳 까지 iterator가 뛰면 끝! so simple!3. 거리 계산엔 distance와 점프엔 advance가 사용된다. 그럼 이렇게 하면 되는가?1advance(i, distance(it, constIt));cs안 된다고 하신다. distance의 선언문을 보자12template typename ierator_traits::differe..
[effective STL] 항목 26 : 여러 iterator 중 쓸만한 것은 결국 iterator 총 4개의 iterator를 제공한다.iterator, const_iterator, reverse_iterator, const_reverse_iterator 일종의 T*, const T*, 그리고 head 부터인지 tail 부터인지 차이다. iterator의 변환 관계는 다음과 같다. iterator가 좋은 이유- 어떤 형태의 insert나 erase 멤버 함수는 무조건 iterator만을 넘겨야 한다.- const_iterator를 iterator로 암묵적 변환할 방법이 없다. 방법이 있지만 성능과 안정성이 보장되지 않는다.- reverse_iterator를 iterator로 변환할 수 있지만 변환 후 약간의 조정이 필요하다. const_iterator와 iterator를 동시에 사용할 시 팁Tip 1..