生成6个随机数时如何检查以确保没有重复?

时间:2019-01-21 23:01:14

标签: c arrays random numbers

我可以将随机数放入数组中,但是我不知道如何检查以确保它们没有重复。我打印出代码,但是数组中没有数字(什么都不打印)。

//puts random numbers into an array
i = 0, j = 0;
srand(time(NULL));
for (i = 0; i < arrSize; i++)
{
  randArr[i] = randNums(1,50);
}

i = 0;
for(i = 0; i < arrSize; i++)
{
  printf("%d ", randArr[i]);
}

printf("\n\n");

//checks to make sure there are no duplicates
i = 0, j = 0, k = 0, temp = 0;
for (i = 0; i < arrSize; i++)
{
  for (j = 1; j <= arrSize;)
  {
    if (randArr[j] == randArr[i])
    {
      for (k = j; k <= arrSize; k++)
      {
        temp = randNums(1,50);
        randArr[k + 1] = temp;
      }
      arrSize--;
    }
    else
      j++;
  }
}

//generates random numbers between the inputed max and min
int randNums(int min, int max)
{
  int result = 0, low = 0, high = 0;
  if (min < max)
  {
    low = min;
    high = max + 1;
  }
  else
  {
    low = max + 1;
    high = min;
  }
  result = (rand() % (high - low)) + low;
  return (result);
}

2 个答案:

答案 0 :(得分:1)

当心!解决此问题的方法有很多,它们都有一个或另一个缺点。如果我要快速实现它,我会选择这样的东西(无需过多进行C魔术操作):

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

#define SIZE (30)
#define RAND_MIN (1)
#define RAND_MAX (50)

static int randNums(int min, int max) {
  // ...
}

int main(void) {
  (void) srand(time(NULL));
  int arr[SIZE];
  int used = 0;
  while (used < SIZE) {
    int  num    = randNums(RAND_MIN, RAND_MAX);
    bool exists = false;
    for (int i = 0; i < used; ++i) {
      if (arr[i] == num)
        exists = true;
    }
    if (exists == false)
      arr[used++] = num;
  }
  for (int i = 0; i < SIZE; ++i)
    (void) printf("%d\n", arr[i]);
  return EXIT_SUCCESS;
}

我希望这会有所帮助:)

答案 1 :(得分:0)

this answer类似,您可以执行rejection sampling,但是对于非常简单的哈希集,固定数量的样本的均匀分布是理想的。 (尽管渐近运行时可能与n=6无关。)

#include <stdlib.h> /* (s)rand */
#include <stdio.h>  /* printf */
#include <time.h>   /* clock */
#include <assert.h> /* assert */

/* Double-pointers are confusing. */
struct Reference { int *ref; };

/* Simple fixed hash set. */
static struct Reference bins[256];
static int nums[6];
static const size_t no_bins = sizeof bins / sizeof *bins,
    no_nums = sizeof nums / sizeof *nums;
static size_t count_num;

/* Uniformly distributed numbers are great for hashing, but possibly clump
 together under linear probing. */
static size_t hash(const int n) { return ((size_t)n * 21) % no_bins; }

/* Linear probing. */
static struct Reference *probe(const int n) {
    size_t bin_index;
    struct Reference *bin;
    assert(sizeof bins > sizeof nums);
    for(bin_index = hash(n); bin = bins + bin_index,
        bin->ref && *bin->ref != n; bin_index = (bin_index + 1) % no_bins);
    return bin;
}

/* Return whether it's a new value. */
static int put_in_set(const int n) {
    struct Reference *bin = probe(n);
    int *num;
    assert(count_num < no_nums);
    if(bin->ref) return 0; /* Already in hash. */
    num = nums + count_num++;
    *num = n;
    bin->ref = num;
    return 1;
}

/* http://c-faq.com/lib/randrange.html */
static int rand_range(const unsigned n) {
    unsigned int x = (RAND_MAX + 1u) / n;
    unsigned int y = x * n;
    unsigned int r;
    assert(n > 0);
    do {
        r = rand();
    } while(r >= y);
    return r / x;
}

/* Generates random numbers between the inputed max and min without
 repetition; [min, max] inclusive. */
static int unique_uniform(const int min, const int max) {
    int n;
    assert(min <= max && (size_t)(max - min) >= count_num);
    do { n = rand_range(max - min + 1) + min; } while(!put_in_set(n));
    return n;
}

int main(void) {
    int n = 6;
    srand((int)clock()), rand(); /* My computer always picks the same first? */
    while(n--) { printf("%d\n", unique_uniform(1, 50)); }
    return EXIT_SUCCESS;
}

但是,如果数字密集排列(例如unique_uniform(1, 6)),它将拒绝很多数字。另一种解决方案是将Poisson个分布式数字作为运行总和(递归T(n+1)=T(n)+\mu_{n+1}),其中期望值是数字范围除以总样本的数量,然后取random permutation