M$ C++ 컴파일러 2003에서 나름대로 random_sample_n 쓰기
글쓴이: danskesb / 작성시간: 수, 2006/05/03 - 10:03오후
쌍둥이: http://ubuntu.ksa.hs.kr/~psj/blog/node/75
추가: 이 함수는 SGI의 확장 구현입니다.
Microsoft C++ Compiler 2003의 algorithm
헤더에는 <a href="http://www.cppreference.com/cppalgorithm/random_sample_n.html">random_sample_n</a>
함수가 없다는 것을 알게 되었다. 이유인 즉슨, 현재 작성중인 QOM의 일부만 돌기 기능을 구현하다가 몇개만 랜덤으로 추출하는 STL에 대해서 동작하는 함수가 필요했는데, 구글신은 이 함수를 권해 주었다. 그래서, 쓰고 있는 VS.NET 2003에 이 코드를 집어넣고 돌렸다.
std::vector<Wordlet> tmpvec; random_sample_n(tmpset.wordsets.begin(), tmpset.wordsets.end(), tmpvec.begin(), word_count); tmpset.wordsets = tmpvec;
보시다시피
vector
클래스를 분명히 존재하는 함수로 컴파일해 가고 있었다. 그런데 결과는...------ 빌드 시작: 프로젝트: libQOpenMemory, 구성: Release Win32 ------ 컴파일하고 있습니다. libqopenmemory.cpp libqopenmemory.cpp(220) : error C3861: 'random_sample_n': 인수 종속성을 조회해도 식별자를 찾을 수 없습니다. 빌드 로그가 "file://d:\자작 프로그램\QtOpenMemory\libQOpenMemory\Release\BuildLog.htm"에 저장되었습니다. libQOpenMemory - 1 오류, 0 경고
그래서, 이것을 둘러가기 위해서 코드를 꽤 많이 고쳤다.
std::vector<Wordlet> tmpvec; std::vector<Wordlet>::iterator i; tmpvec = tmpset.wordsets; random_shuffle(tmpvec.begin(), tmpvec.end()); i = tmpvec.begin(); i += word_count; tmpvec.erase(i, tmpvec.end()); tmpset.wordsets = tmpvec;
간단하게 설명하면, 원본 벡터의 내용을 복사해 온 다음에 섞어서 n개 추출하고 n 이상의 부분을 지우는 식으로 작동한다. 좀 더 일반적으로 써서 함수를 만들어 보자.
std::vector<T> random_sample_n(std::vector<T> orig, int count){ std::vector<T> retvalue; std::vector<T>::iterator i; retvalue = orig; random_shuffle(retvalue.begin(), retvalue.end()); i = retvalue.begin(); i += count; retvalue.erase(i, retvalue.end()); return retvalue; }
안타깝게도 테스트는 못 해 봤다. 본인이 템플릿을 잘 못 다루므로 T 앞에 적절한 템플릿 관련 키워드를 추가시켜 주길 바란다.
Forums:
데이터 전체를
데이터 전체를 shuffle하는 것 보다는 Programming Pearls의 A sample problem에 인용된 Knuth의 S 알고리즘을 사용하는 것이 효율적입니다.
댓글 달기