2018년 10월 29일 월요일

std::random_shuffle, std::shuffle

예전에 처리했던 방법
처음부터 순회하면서 랜덤한 위치의 값과 바꾼다.

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 );

template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc& r );


template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc&& r );


template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );




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

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)]);
    }
}

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))]);
    }
}

댓글 없음:

댓글 쓰기