如何随机地在向量中混洗元素

时间:2014-04-03 22:39:54

标签: c++ vector

我正在尝试执行需要执行以下操作的任务:

  1. 请求所需数量的元素n。
  2. 使用元素0,1,2,...,n - 1填充矢量并将其显示到控制台。
  3. 随机随机播放元素并将新排列显示在控制台上。
  4. 我输入了矢量,但我无法弄清楚如何改变矢量。

    注意:我不能使用random_shuffle函数或任何函数(除了.swap()或索引),所以不要这样做。

    到目前为止我所拥有的是

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <ctime>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
        srand(time(NULL));
        vector<int> elements;
        int sizeOfVector;
        // size of the vector
        cout << "Please enter the size of the vector: " << endl;
        cin >> sizeOfVector;
        cout << "This is your vector:" << endl;
        // Output each element in the vector
        for (int i = 0; i < sizeOfVector; ++i) {
            elements.push_back(i);
            cout << i << " ";
        }
        cout << endl;
        system("pause");
        return 0;
    }
    

    所以是的,再一次,我似乎无法获得的是如何在不使用random_shuffle函数的情况下将元素在不同的位置进行混洗

    我已尝试使用Fisher-Yates shuffle,但它只是重复了这个向量:

    for (int k = 0; k < sizeOfVector; k++)
    {
        int r = rand() % sizeOfVector;
        swap(elements[k], elements[r]);
        cout << k << " ";
    }
    

    更新 感谢用户Danvil,他修复了它。

    // first shuffle
    for (int k = 0; k < sizeOfVector; k++) {
        int r = k + rand() % (sizeOfVector - k); // careful here!
        swap(elements[k], elements[r]);
    }
    
    // THEN print
    for (int k = 0; k < sizeOfVector; k++) {
        cout << elements[k] << " ";
    }
    

2 个答案:

答案 0 :(得分:6)

使用std::random_shuffle中定义的<algorithm>。请参阅here

为什么不想使用此功能?您可以选择复制它的源代码并命名函数my_random_shuffle - 但这显然是愚蠢的。

顺便说一下,该算法被称为Fisher-Yates shuffle

更新:您的算法实现基本上是正确的,但您需要这样做:

// first shuffle
for (int k = 0; k < sizeOfVector; k++) {
    int r = k + rand() % (sizeOfVector - k); // careful here!
    swap(elements[k], elements[r]);
}

// THEN print
for (int k = 0; k < sizeOfVector; k++) {
    cout << elements[k] << " ";
}

答案 1 :(得分:1)

使用Fisher-Yates shuffle。你目前的尝试有几个错误。

首先,这一行:

cout << k << " ";

输出索引,而不是元素。你认为它正在输出原始的,无组合的向量,但这只是一个巧合,因为你用0,...,n - 1填充向量,这恰好与向量索引相同。将行更改为:

cout << elements[k] << " ";

您的实施也不正确。在Fisher-Yates中,在每次迭代中,您将元素与在所有剩余未访问元素中随机选择的元素交换,包括元素本身。在您的实现中,您将使用从整个向量中随机选择的一个进行交换。