1

我对 C++ 很陌生,本周要完成一项非常艰巨的任务。我不会详细介绍它,因为我不想为我完成工作,但是谁能指出我将如何从多维字符串数组中选择随机字符的正确方向?

char gameZero[16][6] = { {'A','A','C','I','O','T'}, {'A','H','M','O','R','S'}, {'E','G','K','L','U','Y'}, {'A','B','I','L','T','Y'}, {'A','C','D','E','M','P'}, {'E','G','I','N','T','V'}, {'G','I','L','R','U','W'}, {'E','L','P','S','T','U'}, {'D','E','N','O','S','W'}, {'A','C','E','L','R','S'}, {'A','B','J','M','O','Q'}, {'E','E','F','H','I','Y'}, {'E','H','I','N','P','S'}, {'D','K','N','O','T','U'}, {'A','D','E','N','V','Z'}, {'B','I','F','O','R','X'} };

目标是打印出这些字符的 4x4 棋盘,在每场游戏开始时从每个数组中随机选择一个字符,这样棋盘就不一样了。

任何有关如何执行此操作的建议/提示将不胜感激 - 谢谢!

编辑:

我已经到了可以从两个数组生成随机索引的地步,但是我目前的做法只输出一个字符,而我需要从数组中的 16 个分类中的每个分类中获取一个字符。关于如何从每个输出一个的任何想法?我想我必须将索引生成器放在某种循环中。

mt19937 gen(time(nullptr)); // random number generator

// used to generate random number in specific range 
uniform_int_distribution<int> random_outer(0, outer_size - 1);
uniform_int_distribution<int> random_inner(0, inner_size - 1);

int index_outer = random_outer(gen); // used to generate random outer index
int index_inner = random_inner(gen); // used to generate random inner index

cout << gameZero[index_outer][index_inner] << endl;
4

4 回答 4

2

您可以使用以下算法:

  • 在区间内生成随机数 x[0, std::size(gameZero )[
  • 在区间内生成随机数 y[0, std::size(gameZero[0])[
  • 访问gameZero[x][y]二维数组的随机字符。
于 2019-10-06T23:58:50.833 回答
0

感谢所有在此线程中做出回应的人的帮助,我相信我已经为我的问题找到了一个合理的答案。如果有人碰巧遇到这个线程,这就是我想出的:

void shuffleDice() { // shuffles Game #0 dice. 

mt19937 gen(time(nullptr));
uniform_int_distribution<int> random_inner(0, inner_size - 1);

int n = random_inner(gen); // generates random number for inner array 
for (int i = 0; i < 16; i++) // loops through outer array
{
    cout << gameZero[i][n] << '\n';
}

请记住,我是编程/C++ 新手,所以它可能不是最漂亮的,但它仍然有效。

于 2019-10-07T14:37:43.843 回答
0

给定您gameZero的类型char[16][6],您只需要生成一个随机数,它表示从范围开始的偏移gameZero(0, sizeof gameZero)。任何基本类型 ( char, int, double, etc...) 的数组都保证在内存中是连续的。此外,在您使用 type 的情况下char,每个char都是 1 字节。gameZero因此,您可以通过计算距数组开头的偏移量来访问其中的任何字符。

如您所见,C++ 提供了自己的Pseudo-random number generation。您可以选择任何一种分发引擎来创建随机分发。当您需要一个随机数时,使用您的发行版进行调用,传递您创建的实例作为其参数的引擎。例如,要使用std::mersenne_twister_engine创建随机分布,您可以这样做:

#include <random>
...
    char gameZero[16][6] = {{'A','A','C','I','O','T'}, 
    ...
    std::random_device rd;              /* random device/seed */
    std::mt19937 gen(rd());             /* standard mersenne_twister_engine */
    std::uniform_int_distribution<> dist(0, sizeof gameZero);    /* dist */

然后为了选择一个随机元素代表gameZero你的偏移量,只需使用以下命令请求一个随机数:

        int off = dist(gen);        /* get random offset in gameZero */

从偏移量中,可以简单地通过使用数组中的列数(在您的情况下)来计算其中的[x][y]元素,例如gameZero6

        int x = off / 6,            /* compute row from offset */
            y = off - 6 * x;        /* compute col from offset */

注意:整数除法是有​​意计算x上面的(行)值)

然后,您可以简单地使用 访问随机元素gameZero[x][y]

例如,如果在循环中请求随机偏移量并[x][y]按照上述说明计算索引,则可以输出偏移量、计算的索引和该索引处的字符,类似于以下内容:

$ ./bin/randarr2d
92 - gameZero[15][2] = F
 9 - gameZero[ 1][3] = O
14 - gameZero[ 2][2] = K
91 - gameZero[15][1] = I
86 - gameZero[14][2] = E
46 - gameZero[ 7][4] = T
92 - gameZero[15][2] = F
33 - gameZero[ 5][3] = N
87 - gameZero[14][3] = N
57 - gameZero[ 9][3] = L
87 - gameZero[14][3] = N
50 - gameZero[ 8][2] = N
10 - gameZero[ 1][4] = R
23 - gameZero[ 3][5] = Y
...

理解,您也可以单独使用偏移量直接访问元素,但这会导致技术上违反数组边界。(例如*(*gameZero + off))短篇小说是二维数组实际上是一维数组的数组。当您访问一个数组时,它会转换为指向其第一个元素的指针。在二维数组的情况下,这是指向第一个数组的指针。(在您的情况下是第一个 6 字符数组),因此如果您应用超过 5 的偏移量,即使您仍在 2D 数组的范围内,您在技术上也正在处理第一个 1D 数组范围之外的元素. 从单个偏移量计算x, y索引消除了这个问题。

如果您有任何其他问题,请仔细查看并告诉我。

于 2019-10-07T05:15:53.980 回答
0
  • 提供一个包含 6 个项目的 int 列表。
  • 使用 0 - 5 的索引值对其进行初始化。
  • 对于板上的每个单元格: //from 0 - 15.
    • 打乱 int 列表。
    • 对于您拥有的每个 4x4 板://假设最多 6 个。
      • 使用索引 iBoard 处的 int 列表中的项目设置当前板的当前单元格。
        • //example: board[iBoard][iCell] = listInt[iBoard]
于 2019-10-07T01:04:27.433 回答