简体   繁体   English

无重复数的随机数组

[英]Random Array with no repeated numbers

So what I am trying to do is create a random array of 5 elements, those elements should be filled with numbers from 1 to 6 and they shall not repeat, I can't tell where my logic is wrong. 所以我想做的是创建一个由5个元素组成的随机数组,这些元素应该用1到6的数字填充,并且它们不应重复,我不能说出我的逻辑错在哪里。

void genNumber(int vet[]){
   int max, i, j, atual;
   srand(time(NULL));

   max = 7;
   for (i=0;i<5;i++){
      vet[i] = rand() % max;
      while(vet[i] == 0){
         vet[i] = rand() % max;
      }

      for(j=0;j<i;j++){
         atual = vet[j];
         while((vet[i] == atual)||(vet[i] == 0)){
            vet[i] = rand() % max;
            atual = vet[j];
         }
      }
   }
}

Update: Fixed 更新:固定

void genNumber(int vet[]){
int max, i, j;
srand(time(NULL));

max = 7;
for (i=0;i<5;i++){
    vet[i] = rand() % (max-1) + 1;

    for(j=0;j<i;j++){
        while(vet[j] == vet[i]){
            vet[i] = rand() % (max-1) + 1;
            j = 0;
        }
    }
}
}

The logical flaw is in the way you produce a new random number when a duplicate is found. 逻辑缺陷在于找到重复项时您会产生一个新的随机数。

Imagine you already have vel = {1,2,0,0,0,...} and are trying to find a number for vel[2] . 假设您已经有vel = {1,2,0,0,0,...}并正在尝试为vel[2]查找一个数字。 If you randomly draw a 2 , you'll find it's already there and draw again. 如果您随机绘制2 ,则会发现它已经存在并再次绘制。 But if you draw a 1 this time you won't notice, because you only compare to the last value seen, 2 in the example. 但是,如果这次绘制1您将不会注意到,因为您只比较了上一个看到的值,在示例中为2 So you'd get vel = {1,2,1,...} . 因此,您将获得vel = {1,2,1,...}

"Solution": Every time you draw a new random number you have to compare it against all numbers already in the list. “解决方案”: 每次绘制新的随机数时,都必须将其与列表中已有的所有数字进行比较。

Another way of solving this is the one I tried to outline in the comments: You have to keep the information about which numbers are still valid for a draw somewhere. 解决此问题的另一种方法是我尝试在评论中概述的一种方法:您必须将有关哪些数字对于抽奖仍然有效的信息保留在某处。 You can either use the "output" array for that as you're doing now, or you can use another store from which you "remove" an entry once it was drawn. 您可以像现在一样使用“输出”数组,也可以使用另一个存储区,在绘制该存储区后就可以从中“删除”该条目。

when generating a random number,you have to check if it is found in the array,so iterate over the array and check.if the number is found,generate another random number and check,until the new number is not found in the array.after that assign it.and repeat. 生成随机数时,必须检查是否在数组中找到该数字,然后遍历该数组并进行检查。如果找到该数,请生成另一个随机数并进行检查,直到在数组中找不到新数字为止。之后分配它。并重复。

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

int check(int vet[],size_t size,int val);

void genNumber(int vet[],size_t size);

int main(void)
{
    srand(time(NULL));

    int vet[5];

    size_t size = 5;

    genNumber(vet,size);

    for( size_t n = 0 ; n < size ; n++ )
    {
        printf("%d ",vet[n]);
    }
}

void genNumber(int vet[],size_t size)
{
    int num = rand() % 6 + 1;

    vet[0] = num;

    for( size_t n = 1 ; n < size ; n++ )
    {
        num = rand() % 6 + 1;
        while( 1 )
        {
            if( check(vet,n,num) )
            {
                num = rand() % 6 + 1;
            }
            else
            {
                vet[n] = num;
                break;
            }
        }
    }
}

int check(int vet[],size_t size,int val)
{
    for( size_t n = 0 ; n < size ; n++ )
    {
        if( vet[n] == val )
        {
            return 1;//FOUND
        }
    }
    return 0;//NOT FOUND
}

As an alternative you can fill an array with a value from 1 to 6. Afterwards you can shuffle the array at random indicies. 或者,您可以使用1到6之间的值来填充数组。然后,您可以按随机索引对数组进行随机排序。

#define MAX 6

void swap (int *a, int *b) {
  int temp = *a;
  *a = *b;
  *b = temp;
}

void genNumber(int *vet) {
  int i;

  for(i=0;i<MAX;i++) {
    vet[i] = i+1;
  }

  for(i = MAX-1;i > 0;i--) {
    // Pick a random index from 0 to i
    int j = rand() % (i+1);
    // Swap vet[i] with the element at random index
    swap(&vet[i], &vet[j]);
  }
}

Also you shouldn't call srand(time(NULL)); 另外,您不应该调用srand(time(NULL)); inside of the genNumber function if you intend to call it more than once, becaues otherwise it will give you the same numbers if you call it more than once a second. 如果您打算多次调用它,请在genNumber函数内部进行,因为genNumber如果genNumber调用一次以上,它将给您相同的数字。

Afterwards just use the first five elements from the array. 然后,仅使用数组中的前五个元素。 So you would call it like this from main 所以您可以从main这样称呼它

int vet[MAX] = {0};
srand(time(NULL));
genNumber(vet);
for(i=0;i<5;i++) {
  printf("after num %d\n", vet[i]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM