STL.NET Primer (3/4)에서 이어지는 글입니다.
알고리즘 선택하기
지네릭 알고리즘은 STL/STL.NET 컨테이너에 담긴 요소와 두가지 내장 배열 타입에 담긴 요소 모두에 운용됩니다. 지네릭 알고리즘은 검색(find, count), 정렬(merge, partition, permutate, reverse, rotate, shuffle, sort), 삭제/치환(remove, replace, swap, unique), 복사, 관계(equal, min, max, includes), 산출(fill, for-each, generate, transform), 설정(union, intersection, difference), 힙(make, sort, pop, push) 연산을 지원할 뿐만 아니라, 축적(accumulate), 부분합(partial sum), 내적(inner product), 인접차(adjacent difference)과 같은 난해한 수치 연산도 지원합니다.
물론 이들 지네릭 알고리즘을 사용하기 위해서는 해당 헤더 파일을 포함해야 합니다. 수치 알고리즘을 제외한 모든 알고리즘의 경우에는 다음과 같이 작성합니다.
#include <algorithm>
C++
복사
축적(accumulate), 부분합(partial_sum), 내적(inner_product), 인접차(adjacent_difference)라는 네가지 수치(numeric) 알고리즘은 다른 헤더 파일에 들어 있습니다. 이들 알고리즘을 사용하려면, 아래와 같이 작성합니다.
#include <numeric>
C++
복사
(저는 이들 네가지 알고리즘이 왜 다른 헤더 파일로 떨어져 나왔는지를 알아내려 했습니다. - 이로 인하여 이들 알고리즘을 사용하기가 분명 까다로와집니다. - 하지만 문서에서건 사람들에서건 간에 이에 대한 명확한 설명을 찾아볼 수 없었습니다. Stepanov가 구현한 원 구현 코드에는 이들 네가지가 그 외의 알고리즘과 함께 한 헤더 파일안에 담겨있습니다. 하지만 표준화 작업이 이루어지는 와중 수치 헤더가 등장하여, 결국 이 헤더는 표준에서 따로 세분화된 수치 라이브러리에 관한 논의로 옮겨갔습니다.)
여러분은 이렇게 생각할지도 모르겠습니다. "잠깐요, Stan, 이 헤더 파일의 모양은 <cli/algorithm>이 되어야 하는 것 아닌가요? 결국 이 컨테이너의 헤더 파일이 어떻게 한정(qualify)되느냐의 것이까요. 실수하신거 아녀요?" '놀랍게도' 이 질문에 대한 대답은 "아니요" 입니다. 저는 지금 '놀랍게도'라고 말했는데, 왜냐하면 이들 알고리즘을 구현한 코드는 네이티브 STL과 STL.NET 모두에서 사용되고 있기 때문입니다. 그렇죠, 바로 코드 재사용입니다!
좋습니다. 이제 이들 알고리즘을 어떻게 사용하는지에 대해 살펴보기로 하죠. 그 예로서, String 요소들을 map에 넣기 전에 이들 요소가 담긴 배열을 정렬해보기로 하죠. 우리는 이 작업에 sort() 지네릭 알고리즘을 이용할 것입니다. 거의 모든 지네릭 알고리즘과 마찬가지로, 인수는 범위를 나타내는 한쌍의 반복자입니다.
sort( &as[0], &as[ as->Length ] );
C++
복사
이 컬럼의 처음에서 보았던 코드에서는 두 개의 알고리즘, 즉 find()과 remove()가 사용되었습니다.
// 지네릭 알고리즘: find
vector<String^>::iterator iter =
find( svec->begin(), svec->end(), "Pooh" );
if ( iter != svec->end() ) { ...}
// 지네릭 알고리즘: remove ...
remove( svec->begin(), svec->end(), "Rabbit" );
C++
복사
이 코드에서는 사용 패턴에 집중해야 합니다: 알고리즘과 컨테이너과의 연결은 반복자 쌍에 의한 지정된 범위에 의해 이루어집니다. 검색 알고리즘은 컨테이너 내에서 아이템을 찾았을 경우에는 그 아이템에 대한 반복자를 반환하고, 실패했을 경우에는 지정된 범위의 마지막에서 하나 지난 곳을 가리키는 반복자를 반환합니다.
저는 이들 지네릭 알고리즘을 통한 흥미로운 작업을 보여줄 터이지만, 아쉽게도 이 작업은 나중에 이어질 컬럼에서야 나타날 것입니다. 이 컬럼이 여러분에게의 STL.NET에 관한 만족스러운 소개글이 되었었으면 하는 바램이며, 이 컬럼이 STL.NET에 대한 기본 용어와 기반 지식을 제공함으로써, 여러분 또한 STL.NET으로 나아가게 되기를 바랍니다. 다음에 다시 뵙도록 하죠.
감사의 말
세 상에는 언제나 이러한 간단한 컬럼조차 묻혀버리지 않도록 도움을 주는 수많은 보이지 않는 손이 존재합니다. 최종 원고에서조차 보여주었던 저의 잘못된 생각(으하!).. 이에 대해 사려깊은 리뷰를 해주었던 Scott Currie에게 저는 엄청난 감사의 빚을 지고 있습니다. Anson Tsao는 인내심을 갖고 STL.NET에 대한 가르침을 주었으며, 이에 너무나도 감사하다는 말을 전합니다. Martyn Lovell은 STL.NET이 세상에 선보이기까지의 조타수 역할을 하고 있으며, 저에게 STL.NET에 관한 많은 것들을 보여주었습니다. 마지막으로, Brian Johnson과 Ronald Laeremans에게도 감사의 말을 전합니다.
필자에 관하여
스탠 립먼(Stan Lippman)은 마이크로소프트 내 Visual C++팀의 아키텍트입니다. 그는 벨 연구소(Bell Laboratories)에서 C++의 창시자인 Bjarne Stroustrup과 함께 C++로 작업하기 시작했으며, 그 시점은 1984년까지 올라갑니다. 그간 그는 디즈니(Disney)와 드림웍스(DreamWorks)의 애니메이션(Feature Animation) 제작자의 일원이었으며, 판타지아 2000(Fantasia 2000)의 소프트웨어 기술 책임자(Software Technical Director)였습니다.