티스토리 뷰

IT지식

std::random_shuffle, std::shuffle

민자르 2018. 4. 14. 03:38
반응형

예전에 처리했던 방법

처음부터 순회하면서 랜덤한 위치의 값과 바꾼다.


void Shuffle(int * index, int nMax)

{

int i, n;

int tmp;


for (i=nMax-1;i>=0;i--)

{

n = rand() % nMax;

tmp = index[i];

index[i] = index[n];

index[n] = tmp;

}

}



요즘은 아래와 같이 코딩으로 처리한다.


#include <random>

#include <algorithm>

#include <iterator>

#include <iostream>

 

int main()

{

    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

 

    std::random_device rd;

    std::mt19937 g(rd());

 

    std::shuffle(v.begin(), v.end(), g);

 

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));

    std::cout << "\n";

}


Result :

10 6 8 7 2 3 4 9 5 1



자세한 내용과 다른 방법을 알고 싶으면 아래를 살펴 보면 된다.



Defined in header <algorithm>
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );
(1)(deprecated in C++14) 
(removed in C++17)
(2)
template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc& r );
(until C++11)
template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc&& r );
(since C++11) 
(deprecated in C++14) 
(removed in C++17)
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );
(3)(since C++11)


내부적으로 처리 방법을 보면 특별하지 않다. 이미 익히 알고 있는 방법과 다르지 않다.

template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last )
{
    typename std::iterator_traits<RandomIt>::difference_type i, n;
    n = last - first;
    for (i = n-1; i > 0; --i) {
        using std::swap;
        swap(first[i], first[std::rand() % (i+1)]);
        // rand() % (i+1) isn't actually correct, because the generated number
        // is not uniformly distributed for most values of i. A correct implementation
        // will need to essentially reimplement C++11 std::uniform_int_distribution,
        // which is beyond the scope of this example.
    }
}


template
<class RandomIt, class RandomFunc> void random_shuffle(RandomIt first, RandomIt last, RandomFunc&& r) { typename std::iterator_traits<RandomIt>::difference_type i, n; n = last - first; for (i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[r(i+1)]); } }


template
<class RandomIt, class URBG> void shuffle(RandomIt first, RandomIt last, URBG&& g) { typedef typename std::iterator_traits<RandomIt>::difference_type diff_t; typedef std::uniform_int_distribution<diff_t> distr_t; typedef typename distr_t::param_type param_t;   distr_t D; diff_t n = last - first; for (diff_t i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[D(g, param_t(0, i))]); } }




728x90
반응형
댓글