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

问题描述 投票:2回答:3

我想编写一个程序,以便每次运行时打印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;
}
c random numbers
3个回答
0
投票

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;
}

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

(如果您查找“随机排列”或“Fisher-Yates shuffle”,那么您将找到更有效的算法来生成非重复的随机数序列。)


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++)部分。其结果被其他部分覆盖。


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


0
投票

使用移位掩码算法,您可以生成非随机数,非重复。我在下面列出了我的一个函数,给出了一个例子。此过程比任何其他提供的算法快10倍,也不使用额外的内存。这种算法通常用于“数字溶解”和“散射”效果等,但是我的实现集中在单维效果上。

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 */
}
© www.soinside.com 2019 - 2024. All rights reserved.