控制数组中元素的出现

时间:2021-04-18 21:37:31

标签: arrays c function multidimensional-array nested

我想创建一个 NxN 二维数组并填充它随机数,直到它达到 (N*N)-1st 项。 例如,如果我有 5x5,那么我应该将它从 1 填充到 15(一个将保持为空)。 但不应该有任何重复。这是我的代码:

for(i=0; i<N; i++)
{
    for(j=0; j<N; j++)
    {
       array[i][j] = (rand() % (n*n-1)) + 1;   /* (rand() % (max - min + 1)) + min */
       count++; 
       if(count > 1)
       {
          for(k=count; k>0; k--)
          {
             if(is_same(array, array[i][j], n) != 0)
                array[i][j] = (rand() % (n*n-1)) + 1;
          } 
        }     
     }
}

为了防止重复,我写了 is_same 函数:

int is_same(int arr[][N], int control, int n)
{
   int i,j;
   for(i=0; i<n; i++)
   {
      for(j=0; j<n; j++)
      {
         if(control == arr[i][j])
            return 1;   /* If our integer is same with befores, func will return 1 and we'll select another integer */
      }
   }
   return 0;
}

问题是,在嵌套循环部分,我无法控制 is_same 函数的返回值。我尝试使用 while 循环,但在编译代码时它冻结了。制作计数器并检查计数器数量的结果也不起作用。 (上面的代码段)我该如何解决这个问题?非常感谢!

1 个答案:

答案 0 :(得分:0)

对于您的非洗牌解决方案,如果您检测到“重复”,您将相同等式与 rand 一起使用,因此您可以得到相同的号码(即 no 更改以修复号码)。

或者,您可以获得一个新号码,该号码是另一个单元格的副本。

所以,你可能会得到重复。而且,您不会检查所有 其他单元格。而且,由于您正在检查,因此您甚至没有所有数字来检查重复项。

以这种方式进行重复检查 [至少] O(N^2)--或更糟。对于每个新数字(例如 array[i][j]),您必须检查所有以前的数字,例如 [这是未经测试的]:

for (int inew = 0;  inew < N;  ++inew) {
    for (int jnew = 0;  jnew < N;  ++jnew) {
        while (1) {
            int newval = (rand() % (n*n-1)) + 1;

            int dupflg = 0;
            int *arrnew = &array[inew][jnew];
            int *arrchk = &array[0][0];

            for (;  arrchk < arrnew;  ++arrchk) {
                dupflg = (*arrchk == newval);
                if (dupflg)
                    break;
            }

            if (! dupflg) {
                array[inew][jnew] = newval;
                break;
            }
        }
    }
}

在接近尾声时可能需要很长时间才能获得可以存储的新/唯一 newval(即它是无界的)。


这就是为什么[正如意识到和其他人提到的],洗牌是要走的路。这是一个使用 shuffle [有点粗糙] 的重构版本:

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

#ifndef N
#define N       7
#endif

#define N2      (N * N)

int array[N][N];

void
print_array(const char *why)
{

    printf("%s:\n",why);
    for (int i = 0;  i < N;  ++i) {
        printf(" %d:",i);
        for (int j = 0;  j < N;  ++j)
            printf(" %d",array[i][j]);
        printf("\n");
    }
}

void
fill_array(int tstno)
{

    if (tstno > 1)
        printf("\n");
    printf("TST: %d\n",tstno);

    int val = 1;

    for (int i = 0;  i < N;  ++i)
        for (int j = 0;  j < N;  ++j)
            array[i][j] = val++;

    print_array("orig");

    int *arr = &array[0][0];
    for (int idst = 0;  idst < (N * N) - 1;  ++idst) {
        int isrc = (rand() % (N2 - idst)) + idst;

        val = arr[idst];
        arr[idst] = arr[isrc];
        arr[isrc] = val;
    }

    print_array("shuf");
}

int
main(void)
{

    for (int tstno = 1;  tstno <= 3;  ++tstno)
        fill_array(tstno);

    return 0;
}

这是随机输出:

TST: 1
orig:
 0: 1 2 3 4 5 6 7
 1: 8 9 10 11 12 13 14
 2: 15 16 17 18 19 20 21
 3: 22 23 24 25 26 27 28
 4: 29 30 31 32 33 34 35
 5: 36 37 38 39 40 41 42
 6: 43 44 45 46 47 48 49
shuf:
 0: 16 24 21 29 28 3 33
 1: 38 32 31 13 6 41 12
 2: 5 8 26 20 23 36 15
 3: 22 47 27 9 14 34 49
 4: 30 45 37 25 43 18 17
 5: 4 19 42 11 1 10 39
 6: 48 35 44 40 2 7 46

TST: 2
orig:
 0: 1 2 3 4 5 6 7
 1: 8 9 10 11 12 13 14
 2: 15 16 17 18 19 20 21
 3: 22 23 24 25 26 27 28
 4: 29 30 31 32 33 34 35
 5: 36 37 38 39 40 41 42
 6: 43 44 45 46 47 48 49
shuf:
 0: 24 20 47 48 6 30 44
 1: 17 49 2 5 3 14 23
 2: 19 15 34 27 43 29 32
 3: 16 41 39 21 35 10 9
 4: 40 8 31 46 4 42 13
 5: 36 38 37 26 1 28 18
 6: 33 7 25 45 22 12 11

TST: 3
orig:
 0: 1 2 3 4 5 6 7
 1: 8 9 10 11 12 13 14
 2: 15 16 17 18 19 20 21
 3: 22 23 24 25 26 27 28
 4: 29 30 31 32 33 34 35
 5: 36 37 38 39 40 41 42
 6: 43 44 45 46 47 48 49
shuf:
 0: 40 44 22 21 5 20 11
 1: 36 32 7 46 2 13 14
 2: 42 16 27 15 19 4 41
 3: 35 33 47 1 3 10 31
 4: 9 6 30 43 48 49 24
 5: 17 37 26 34 45 25 28
 6: 38 8 23 39 12 29 18