M$ C++ 컴파일러 2003에서 나름대로 random_sample_n 쓰기

danskesb의 이미지

쌍둥이: 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: 
kewlbear의 이미지

데이터 전체를 shuffle하는 것 보다는 Programming Pearls의 A sample problem에 인용된 Knuth의 S 알고리즘을 사용하는 것이 효율적입니다.

m = c.size();
 
for (it = c.begin(); it != c.end(); ++it) {
  if (rand() % m < n) {
    result.push_back(*it);
    --n;
  }
  --m;
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.