C中的非重复随机数发生器

时间:2014-04-25 06:06:56

标签: c random numbers

我想编写一个程序,以便每次运行时打印10个随机数,打印出来的随机数应为1-10,也不应该重复。

更新:很抱歉没有说明确切的问题,基本上是假设仅在未使用的情况下重新分配随机数的while循环导致我的程序根本不打印任何内容。如果我注释掉整个while循环并将printf保留在底部,它会在1-10之间输出10个随机数,但它只打印出重复。

有人可以告诉我如何修复我的代码或给我一些提示吗?

#include <stdio.h>
#include <time.h>

int main()
{
int array[10];
int x, p;
int count;
int i=0;

srand(time(NULL));

for(count=0;count<10;count++){
array[count]=rand()%10+1;
}

while(i<10){
int r=rand()%10+1;

for (x = 0; x < i; x++)
{
if(array[x]==r){
    break;
}
if(x==i){
    array[i++]=r;
}
}

}
for(p=0;p<10;p++){
printf("%d ", array[p]);
}
return 0;
}

3 个答案:

答案 0 :(得分:0)

因此,{p> if(x==i)for (x = 0; x < i; x++)循环内永远不会成立 while循环永远不会终止。 必须在 for循环后移动if语句:

while(i<10){
    int r=rand()%10+1;

    for (x = 0; x < i; x++)
    {
        if(array[x]==r){
            break;
        }
    }
    if(x==i){
        array[i++]=r;
    }
}

也是第一个循环

for(count=0;count<10;count++){
    array[count]=rand()%10+1;
}

是不必要的,因为稍后会覆盖这些值。

(如果你查找&#34;随机排列&#34;或&#34; Fisher-Yates shuffle&#34; 那么你会发现更有效的算法来产生非重复序列 随机数。)

答案 1 :(得分:0)

(1)你的缩进是错误的。正确的是:

#include <stdio.h>
#include <time.h>

int main()
{
    int array[10];
    int x, p;
    int count;
    int i=0;

    srand(time(NULL));

    for(count=0;count<10;count++){
        array[count]=rand()%10+1;
    }

    while(i<10){
        int r=rand()%10+1;

        for (x = 0; x < i; x++)
        {
            if(array[x]==r){
                break;
            }
            if(x==i){
                array[i++]=r;
            }
        }
    }
    for(p=0;p<10;p++){
        printf("%d ", array[p]);
    }
    return 0;
}

(2)缩进正确后,更容易看到问题。 if(x==i)部分应位于while内,但位于for之外。

#include <stdio.h>
#include <time.h>

int main()
{
    int array[10];
    int x, p;
    int count;
    int i=0;

    srand(time(NULL));

    for(count=0;count<10;count++){
        array[count]=rand()%10+1;
    }

    while(i<10){
        int r=rand()%10+1;

        for (x = 0; x < i; x++)
        {
            if(array[x]==r){
                break;
            }
        }
        if(x==i){
            array[i++]=r;
        }
    }
    for(p=0;p<10;p++){
        printf("%d ", array[p]);
    }
    return 0;
}

这会打印出正确的结果。

(3)您现在可以删除重复填充数组的for(count=0;count<10;count++)部分。其结果被其他部分覆盖。


道德说明:正确的格式化实际上有助于发现错误。不要忽视它。

答案 2 :(得分:0)

使用移位掩码算法,您可以生成非随机数,非重复。我已经在下面列出了我的一个功能示例。此过程比任何其他提供的算法快10倍,也不使用额外的内存。这种算法通常用于&#34;数字解析&#34;和&#34;分散&#34;效果等,但我的实现侧重于单维效果。

享受, B博士

/* Bryan Wilcutt's random scatter algorithm */
/* Generates random-appearing, non-repeating values. */

/* Can be any number within the given range of 32K 
   Mask must be changed for other ranges.  */

#define START_POINT 1

void randScatter()
{
    long mask;  /* XOR Mask */
    unsigned long point;
    int val;
    unsigned int range = 0x7fff; /* 32K */

    mask = 0x6000; /* Range for 32K numbers */

    /* Now cycle through all sequence elements. */

    point = START_POINT;

    do {
        val = point % range;    /* Get random-appearing value */
        printf("%08x\n", val);

        /* Compute the next value */

        if (point & 1) {
            /* Shift if low bit is set. */

            point = (point >> 1) ^ mask;
        } else {
            /* XOR if low bit is not set */

            point = (point >> 1);
        }
    }  while (point != START_POINT); /* loop until we've completed cycle */
}