获取C++中的随机唯一整数

Getting random unique integers in C++

本文关键字:唯一 整数 随机 C++ 获取      更新时间:2023-10-16

我带来了一个格式化的文本文件,并将不同的行放在我的数组中随机位置。但是,当我尝试获取rand() % 8时,我得到了以前已经拥有的值。这导致我丢失了一些行并将数组的某些部分留空。

应该如何修改它,以便我以随机顺序获得从 0 到 7 的唯一值?我只使用我在课堂上学到的东西,老师不推荐新东西。请帮我更改此代码的逻辑。

void get_input(string (&teams)[8][6]) {
    srand(time(NULL));
    string filename;
    double value;
    char buffer[100];
    int diffnum[8];
    string token;
    cout << "Enter the input file: ";
    cin >> filename;
    ifstream infile;
    infile.open (filename.c_str());
    if (infile.is_open()) {
    int teamcounter = 0;
        while (infile.getline (buffer, 100) && teamcounter < 8) {
            int ran = rand()%8;
            for (int find = 0; find < 8; find++) {
                while (diffnum[find] == ran) {
                    ran = rand()%8;
                }
            }
            diffnum[teamcounter] = ran;
            int counter = 0;
            token = strtok (buffer, ",");
            while (counter < 3) {
                if (counter == 0) {
                    teams[ran][counter] = token;
                    token = strtok (NULL, ", ");
                }
                else if (counter == 1) {
                    teams[ran][counter] = token;
                    token = strtok (NULL, ", ");
                }
                else {
                    teams[ran][counter] = token;
                }
                counter++;
            }
            teamcounter++;
        }
        infile.close();
    }
    else {
        cout << "Unable to open file";
        exit (EXIT_FAILURE);
    }
    for (int q =0;q<8;q++) {
        cout << diffnum[q];
    }
    for (int i; i < 8; i++) {
        for (int j = 3; j < 6; j++){
            teams[i][j] = "0";
        }
    }
}

您可能需要考虑生成一个简单的整数序列0,1,2,3,...(max value) 。然后,您可以使用适当的伪随机数生成器shuffle()此序列。

请注意,rand()被认为是有害的,在第 C++14 中不鼓励这样做。

请参阅以下可编译的注释代码:

#include <algorithm>    // For std::shuffle
#include <iostream>     // For std::cout, std::endl
#include <random>       // For std::mt19937, std::random_device
#include <vector>       // For std::vector
int main()
{
    // Fill vector with numbers 0,1,2,3...,kMaxValue
    static const int kMaxValue = 7;
    std::vector<int> v(kMaxValue + 1);
    for (size_t i = 0; i < v.size(); ++i)
        v[i] = i;
    // Random seed generator
    std::random_device rd;
    // Psuedo random number generator
    std::mt19937 prng(rd());
    // Shuffle the 0,1,2,3...,kMaxValue integer sequence
    std::shuffle(v.begin(), v.end(), prng);
    // Print random sequence
    for (int x : v)
        std::cout << x << ' ';
    std::cout << std::endl;
}

现在,要将此知识应用于您的特定函数,您可以定义vector如上所示的唯一(伪随机)整数。

然后,在你的代码中,你已经有一个循环,其中包含一个名为 teamcounter 的索引/计数器,它从 0 到 7(事实上,你在 while 条件中:... && teamcounter < 8 )。
您可以将此teamcounter用作唯一整数向量的索引。因此,与其这样做:

int ran = rand()%8;

您可以简单地从向量中选择伪随机整数:

int ran = vector_of_unique_pseudo_random_integers[teamcounter];

有关 cpp首选项std::shuffle,请参阅此示例:

#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);
    copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << "n";
}

示例输出:

4 1 7 0 3 6 9 2 8 5

您还可以考虑使用 std::iota 填充vector,这将更容易扩展到更大的值。

此外,作为一般规则,更喜欢<random>的设施而不是rand(),这是废话(这是一个技术术语!正如WhozCraig指出的那样,这实际上使用std::shuffle而不是std::random_shuffle。(尽管如果你被困在2011年之前的世界,你可能别无选择)。

要使用 std::iota 填充具有相同值的v,您可以执行以下操作:

std::vector<int> v (10);
std::iota(std::begin(v), std::end(v), 1);
<</div> div class="answers">

这是你想要的:random_shuffle<</p>

div class="answers">这是我

在一个范围内生成随机数的逻辑。

#define SIZE_MAX 8
int getRandom()
{
    static int iBuff[SIZE_MAX] = {0,1,2,3,4,5,6,7};
    static int iPivot = 0;
    int iPos = rand()%(SIZE_MAX-iPivot);
    int result= iBuff[iPos+iPivot];
    //
    // swap values at iPos and iPivot
    //
    int temp = iBuff[iPivot];
    iBuff[iPivot] = iBuff[iPos+iPivot];
    iBuff[iPos+iPivot] = temp;
    iPivot++;
    return result;
}

您可以将从rand() % 8获得的任何数字保存到数组中。稍后您可以在数组中搜索新数字以找到它;如果你找到了它,你可以生成一个新号码,如果没有,你可以使用新号码。