0

我对 c 编程非常陌生,只做过 if/else、循环、数组、指针、函数和结构。如果有人能告诉我如何创建一个包含随时间随机化的二维数组,我将非常高兴,但它的值只会重复两次......

例如意思:

1 2 3 6
8 7 4 5
7 5 6 3
2 1 4 8

实际上我需要数组为 6x6,到目前为止我已经到了这个不起作用的阶段:

int x,y;
int i,j;

srand (time(NULL));

for ( x=0 ; x<6 ; x++){
    for ( y=0 ; y<6 ; y++) {
        sBoard[x][y] = rand() %36;          /*randomization*/

        for ( i=0 ; i<6 ; i++){  /*trying to create an unique array*/
            for ( j=0 ; j<6 ; j++) {
                if ((sBoard[x][y] == sBoard[i][j])) {
                    x--;
                    y--;
                }
            }
        }
        printf ("%i",sBoard[x][y]);
    }
    printf("\n");
}

==================================================== ====================================== 我的讲师让我尝试使用 if 函数来检查该值是否在矩阵的其他任何地方重复...这就是为什么我使用“如果”...如果您能帮助我,我将非常感激...提前谢谢您...

4

4 回答 4

1

问题是您的 if-then 块仍然不能保证该级别的唯一性。你必须有一个while循环才能让它正常工作。这个 while 循环理论上永远不会终止,并且(更有可能)每次运行它时执行的时间都会显着不同。

可能更容易的是用所有值填充二维数组,然后随机播放。你可以作弊,把它当作一维数组,它仍然会以同样的方式工作。这是一些伪代码:

pointer-to-array pArray;
for i = 0 to 35
    pArray[i] = i
numShuffle = 2;
for s = 1 to numShuffle
    for i = 0 to 35
        swap pArray[i] with pArray[random 0 to 34 - if equal, add 1]

这将保证不存在重复,并且您的代码将始终花费完全相同的时间来执行(而不是我上面提到的 while 循环可能永远不会终止)。

您也许可以将 numShuffle 设置为 1 并获得有利的结果。如果你发现这是真的,你甚至不需要那个外循环。

于 2010-11-03T09:27:32.923 回答
0

我对以下内容有点困惑:二维数组是否允许(a)包含最大两倍的特定值或(b)二维数组是否应该始终将每个值精确地保存两次?

(a):建立一个辅助数组,每次保存所有允许的值两次。然后生成一个随机数作为此辅助数组的索引,以选择其中的一个数字并将其存储到所需二维数组的“下一个”位置。不要忘记从辅助数组中删除选择的值。

(b):最初,您可以创建一个 6x6 数组,其中包含 1 到 18 的所有值,每个数组两次。然后,只需通过每次迭代交换两个值来打乱这些值。

编辑:关于您自己的方法和其他一些解决方案建议:我认为试错法不是确保每个值(仅)存储两次的最佳方法。因为从理论上讲,它可能会导致无限循环。是的,我知道,这不太可能发生,但在我看来,它还是有点脏。我更喜欢具有确定性/恒定执行时间的解决方案,以防止不必要的操作。

于 2010-11-03T09:27:04.640 回答
0

第一件事是随机不排除重复本身 - 随机分布就是随机的,并且没有均匀分布的集合,这意味着不会再次出现任何项目。因此,我将首先(为简单起见)将 6x6 2d 数组展平为 36x 1d 数组,然后再对其进行重组。

因此,使用一维数组,您可以循环遍历,并且对于每个位置,在 do 循环中生成一个随机数,然后您可以有一个内部 for 循环,从 0 到当前位置迭代现有数组,如果随机数出现在其中一个位置,标记一个标志表示它已经被看到。这样你就可以用“while(notUnique)”结束do循环。

好的 - 给我看代码!

int board1d[36];
int pos;
for(pos = 0; pos < 36; pos ++) {
  int newRand;
  int notUnique;
  do {
    int innerPos;
    notUnique = 0;
    newRand = rand() % 36;
    for(innerPos = pos; innerPos > 0 && notUnique==0; innerPos--) {
      notUnique = (newRand == board1d[innerPos]);
    }
  } while(notUnique);
  board1d[pos] = newRand;
}

如上所述,这确实意味着如果随机生成器生成一个重复的序列,那么循环将花费更多的周期。在随机集中没有保证均匀分布。

于 2010-11-03T09:29:39.260 回答
0

允许的值范围是多少?假设它不是太大,一些N,我会提出以下算法:

  • 初始化seen为 N 个 int 计数器的数组,指定生成每个值的次数。
  • 遍历您的目标二维数组,生成一个num带有的数字rand
    • 如果seen[num]是2,重新生成num再试一次
    • 否则增加seen[num]并放置num在二维数组中的插槽中

自然,seen必须用全零初始化。

如果数字范围很大(例如,整个整数范围),我会使用哈希表而不是seen数组。

于 2010-11-03T09:21:33.533 回答