我想创建一个 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 循环,但在编译代码时它冻结了。制作计数器并检查计数器数量的结果也不起作用。 (上面的代码段)我该如何解决这个问题?非常感谢!
答案 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