Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 随机置换生成_C_Function_Random_Permutation - Fatal编程技术网

C 随机置换生成

C 随机置换生成,c,function,random,permutation,C,Function,Random,Permutation,我很难从课本中理解这个代码示例。我希望有人能比我的书更好地解释这段代码的一部分。我很抱歉在这个节目中没有评论,所以我会尽我所能在我的问题上非常具体。好的,标题是建议这个程序是“随机排列生成”。我在代码中感到困惑的地方是名为bldPerm()的函数。 函数bldPerm(): 我们想用数字0,…,ARY_SIZE-1的随机排列来填充数组。这意味着这些数字是完全随机排列的 void bldPerm(int randNos[]) { int oneRandno; 我们保留一个名为haveRa

我很难从课本中理解这个代码示例。我希望有人能比我的书更好地解释这段代码的一部分。我很抱歉在这个节目中没有评论,所以我会尽我所能在我的问题上非常具体。好的,标题是建议这个程序是“随机排列生成”。我在代码中感到困惑的地方是名为
bldPerm()的函数。

函数bldPerm():


我们想用数字0,…,ARY_SIZE-1的随机排列来填充数组。这意味着这些数字是完全随机排列的

void bldPerm(int randNos[]) {
    int oneRandno;
我们保留一个名为
haveRand
的数组,它指示是否已经为我们的排列选择了编号
i
。如果选择了编号,则haveRand[i]将设置为1。开始时没有选择任何数字,因此我们使用
0
对其进行初始化

    int haveRand[ARY_SIZE] = { 0 };
对于输出数组中的每个位置,我们随机选择一个尚未选择的数字

    for (int i = 0 ; i < ARY_SIZE; i++)
    {
        do
        {
为此,我们对任意随机数进行采样,并将其称为
oneRandno

            oneRandno = rand() % ARY_SIZE;
我们检查它是否还没有被选中。如果是这种情况,则
haveRand[oneRandno]
为0,while外观将完成。否则,我们继续尝试一种新方法

        } while (haveRand[oneRandno] == 1);
否我们通过将
haveRand[oneRandno]
设置为1,将所选号码标记为已选

        haveRand[oneRandno] = 1;
将所选数字写入输出数组

        randNos[i] = oneRandno;
    }
}
这个算法实际上相当糟糕。。。例如,要填充最后一个元素,只剩下一个候选元素,因为所有其他数字都已选定。但是while循环试图通过随机抽样找到这个数字,这可能需要很长时间


我建议创建一个数字为0到ARY_SIZE-1的数组,并使用来洗牌它们。

我浏览了代码,并用代码写了一些注释,我希望这能澄清问题

void bldPerm(int randNos[]) // here you give an array of random numbers that is empty
{
    // declare an int to store the randomly generated number
    int oneRandno;

    // initialize an array to store random numbers of size ARY_SIZE
    int haveRand[ARY_SIZE] = { 0 };

    // now loop while i is smaller then ARY_SIZE and increment i
    for (int i = 0 ; i < ARY_SIZE; i++)
    {
        // here do generate the random number
        do
        {
            // oneRandno will ALWAYS be between -1 and ARY_SIZE
            // or i.o.w. from 0 to ARY_SIZE - 1
            oneRandno = rand() % ARY_SIZE;
        } 
        // because the numbers have to be unique, if oneRandno
        // was already generated loop again
        while (haveRand[oneRandno] == 1);

        // Set to 1 because the next iteration oneRandno could have the same value,
        // however very unlikely because rand() has a period of at least 2^32 which 
        // gives you enough room to have it generate a whole lot of numbers before 
        // it generates the same number again. So basically the while loop will 
        // never loop and act like a glorified if statement.
        // and that the values in randNos should unique, if oneRandno has the 
        // same value the do while loop will iterate once more 
        // and generate another oneRandno
        haveRand[oneRandno] = 1;

        // finally store the uniquely generated number
        randNos[i] = oneRandno;

        //go to the next iteration
    }
    return;
}
void bldPerm(int randNos[])//这里给出一个空的随机数数组
{
//声明一个int来存储随机生成的数字
int oneRandno;
//初始化数组以存储大小为ARY\u size的随机数
int haveRand[ARY_SIZE]={0};
//现在,当i小于ARY_大小并增加i时循环
对于(int i=0;i
我不认为这是一个糟糕的算法,因为rand()的周期至少为2^32,这给了你足够的空间让它在再次生成相同的数字之前生成大量的数字。所以基本上while循环永远不会循环,就像一个美化的if语句一样。我对它进行了基准测试。对于
ARY_SIZE=20
,while循环平均需要3.6次迭代,对于
ARY_SIZE=200
,需要8.2次迭代。所以没有我想象的那么糟糕,但是Fisher Yates只需要1次迭代。谢谢你的帮助。关于的评论真的帮助我更好地了解情况。现在我明白了为什么do while是这样的,它实际上只是一个if循环,而且很可能不会有重复值,因为rand()的周期是2^32
        randNos[i] = oneRandno;
    }
}
void bldPerm(int randNos[]) // here you give an array of random numbers that is empty
{
    // declare an int to store the randomly generated number
    int oneRandno;

    // initialize an array to store random numbers of size ARY_SIZE
    int haveRand[ARY_SIZE] = { 0 };

    // now loop while i is smaller then ARY_SIZE and increment i
    for (int i = 0 ; i < ARY_SIZE; i++)
    {
        // here do generate the random number
        do
        {
            // oneRandno will ALWAYS be between -1 and ARY_SIZE
            // or i.o.w. from 0 to ARY_SIZE - 1
            oneRandno = rand() % ARY_SIZE;
        } 
        // because the numbers have to be unique, if oneRandno
        // was already generated loop again
        while (haveRand[oneRandno] == 1);

        // Set to 1 because the next iteration oneRandno could have the same value,
        // however very unlikely because rand() has a period of at least 2^32 which 
        // gives you enough room to have it generate a whole lot of numbers before 
        // it generates the same number again. So basically the while loop will 
        // never loop and act like a glorified if statement.
        // and that the values in randNos should unique, if oneRandno has the 
        // same value the do while loop will iterate once more 
        // and generate another oneRandno
        haveRand[oneRandno] = 1;

        // finally store the uniquely generated number
        randNos[i] = oneRandno;

        //go to the next iteration
    }
    return;
}