【面试向】从洗牌算法说起

Fisher-Yates shuffle

Durstenfeld's in-place version

void FY_shuffle(vector<int>& a, int n) {
    default_random_engine e;
    // seed e
    for (int i = n - 1; i > 0; --i) {
        uniform_int_distribution<int> d(0, i);
        int index = d(e);
        swap(a[i], a[index]);
    }
}

现在问题是如何给随机数引擎 e 一个种子(seed)。常见的办法是用系统时间:std::time(nullptr) 或者 std::chrono::system_clock::now().time_since_epoch().count()。但是这种方法有争议,见 https://stackoverflow.com/q/36663027/6052725。

Inside-out version

In this version, one successively places element number \(i\) of the source array into a random position among the first \(i\) positions in the target array, after moving the element previously occupying that position to position \(i\).

void inside_out_shuffle(const vector<int>& source, vector<int>& a, int n) {
    default_random_engine e;
    // seed e
    a[0] = source[0];
    for (int i = 1; i < n; i++) {
        uniform_int_distribution<int> d(0, i);
        int index = d(e);
        if (index != i) {
            a[i] = a[index];
        }
        a[index] = source[i];
    }
}
posted @ 2019-09-18 11:16  Pat  阅读(244)  评论(0编辑  收藏  举报