AcceleratedC++/Chapter4 | AcceleratedC++/Chapter6 |
Contents |
1. Chapter 5 Using sequential containers and analyzing strings ¶
- 여태까지 vector랑 string 갖고 잘 놀았다. 이제 이것들을 넘어서는 것을 살펴볼 것이다. 그러면서 라이브러리 사용법에 대해 더 깊게 이해하게 될것이다. 라이브러리는 자료구조?함수만을 제공해주는 것이 아니다. 튼튼한 아키텍쳐도 반영해준다. 마치 vector의 사용법을 알게 되면, 다른것도 쉽게 배울수 있는것처럼...
1.1. 5.1 Separating students into categories ¶
~cpp bool fgrade(const Student_info& s) { return grade(s) < 60; } vector<Student_info> extract_fails(vector<Student_info>& students) { vector<Student_info> pass, fail; for(vector<Student_info>::size_type i = 0; i != students.size() ; ++i) { if(fgrade(students[i])) fail.push_back(students[i]); else pass.push_back(students[i]); } students = pass; return fail; }
1.1.1. 5.1.1 Erasing elements in place ¶
~cpp vector<Student_info> extract_fails(vector<Student_info>& students) { vector<Student_info> fail; vector<Student_info>::size_type i = 0 while(i != students.size()) { if(fgrade(students[i])) { fail.push_back(students[i]); students.erase(students.begin() + i); } else ++i; } return fail; }
- 왜 students.erase(studentsi) 하지 않는가? 모든 컨테이너에 일관성을 제공하기 위해서라고 한다. 바로 반복자라 불리우는 것을 이용해, (포인터보다 반복자가 먼저 나오네요.) 동일한 방법으로 제어를 할수 있는 것이다.
- 그림 보면 알겠지만, 복사 겁나게 해댄다. 하나 지울때마다 그 뒤에 있는걸 다 복사하는 것이다. 만약에 모두 fail이라면? 끔찍하다.
- 또한, 지워줌으로써 컨테이너의 사이즈가 변한다. 즉 모든 학생을 다 검사하지 못할수도 있다. 그래서 다음과 같이 바꿔주어야 한다.
~cpp vector<Student_info> extract_fails(vector<Student_info>& students) { vector<Student_info> fail; vector<Student_info>::size_type i = 0; vector<Student_info>::size_type size = students.size(); while(i != size) { if(fgrade(students[i])) { fail.push_back(students[i]); students.erase(students.begin() + i); } else ++i; } return fail; }
1.1.2. 5.1.2 Sequential versus random access ¶
- 위의 벡터는 임의 접근이 필요하지 않다. 그냥 순차적으로 접근할 뿐이다. 임의접근을 포기함으로써 생기는 여러가지 이득이 있는 컨테이너가 있을 것이다. 그보다 먼저 컨테이너를 효과적으로 제어할수 있게 해주는 반복자라는 것을 먼저 살펴보자.
1.2. 5.2 Iterators ¶
- 컨테이너와 컨테이너 안의 요소를 확인
- 그 요소 안에 저장되어 있는 값 확인
- 컨테이너 안의 요소들 사이를 왔다갔다 할수 있는 기능
- 컨테이너가 효과적으로 다룰수 있는 연산만을 가지고 놀도록 제한하는 기능
~cpp for(vector<Student_info>::size_type i = 0 ; i != students.size() ; ++i) cout << students[i].name << endl;
~cpp for(vector<Student_info>::const_iterator i = students.begin() ; i != students.end() ; ++i) cout << (*i).name << endl;
1.2.2. 5.2.2 Iterator Operations ¶
1.3. 5.3 Using iterators instead of indices ¶
~cpp vector<Students_Info> extract_fails(vector<Student_info>& students) { vector<Student_info> fail; vector<Student_info>::iterator iter = students.begin(); while(iter != students.end()) { if(fgrade(*iter)) { fail.push_back(*iter); iter = students.erase(iter); } else ++iter; } return fail; }
~cpp while(iter != students.end()) /*...*/
~cpp vector<Student_info>::iterator iter = students.begin(). end_iter = students.end(); while(iter != end_iter) /*...*/
1.4. 5.4 Ranking our data structure for better performance ¶
1.5. 5.5 The list type ¶
1.6. 5.6 Taking strings apart ¶
1.7. 5.7, 5.8 ¶
~cpp for(vector<string>::const_iterator i = bottom.begin(); i != bottom.end(); ++i) ret.push_back(*it);
~cpp ret.insert(ret.end(), bottom.begin(), bottom.end());