如果您仍然卡住,如上面的评论中所述,您想要做的是遍历每一行和每一列并检查可用的邻居是否相等。当当前索引位于边缘或角落时,困难在于限制对所有 8 个邻居的搜索。例如,您的二维数组的维度为ROWS x COLS,并且您循环:
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
您在 和 处位于顶部和底部边缘,在和i == 0处i == ROWS-1位于左侧和右侧边缘。您在 的上角和,的下角。j == 0j == COLS-1[0][0][0][COLS-1][ROWS-1][0][ROWS-1][COLS-1]
有两种方法可以限制对周围邻居的检查,以确保您不会检查数组边界之外的元素。您可以反复循环i并j创建一组相当长的if ... else if ... else if ... else语句,涵盖每个边缘和角落的案例。通过展开您在设置嵌套循环限制时需要捕获的逻辑,基本上避免使用进一步的嵌套循环。这种方法可能具有性能优势,但所需的代码长度可能是嵌套循环所需的 4 到 8 倍。
使用嵌套循环,您需要循环:
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
/* loop from i-1 to i+1 */
/* loop from j-1 to j+1 */
这会产生更短的代码,但需要注意如何为最后两个循环中的每一个设置限制。如果你不熟悉三元,它本质上是一种if ... else ...可以内联使用的速记。基本格式是(condition) ? if_true : if_false. 因此,使用上面的内部循环,您可以限制每个循环的范围 from ito i+1ifi == 0和 from i-1to iif i == ROWS-1(对于列上的内部循环也是如此)
您还需要一个附加条件来避免检查当前索引是否等于自身来创建有效的邻居计数。因此,使用 中的原始元素arr和捕获的每个索引的邻居数sum,您可以执行类似于以下的操作:
for (int i = 0; i < ROWS; i++) { /* loop over each row */
for (int j = 0; j < COLS; j++) { /* loop over each col */
/* loop k from i-1 to i+1, use ternary to omit out of bounds checks */
for (int k = i ? i-1 : i; k <= ((i < ROWS - 1) ? i + 1 : i); k++) {
/* loop l from j-1 to j+1, user ternary to omit out of bounds checks */
for (int l = j ? j-1 : j; l <= ((j < COLS - 1) ? j + 1 : j); l++) {
/* if not comparing element to itself */
if (arr[i][j] == arr[k][l] && !(k == i && j == l))
sum[i][j] += 1; /* increment sum[i][j] */
}
}
}
}
(注意:三元组用于初始化循环计数和设置每个循环的循环限制)
一个完整的例子,它生成一个 10x10 数组,1-10输出数组的随机值,然后用上面的逻辑检查邻居,然后以扫雷格式输出结果,因为缺少更好的单词,其中每个单元格包含周围等效邻居数的计数它,如果没有相等的邻居,则输出空卖,例如
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10 /* if you need a constant, #define one (or more) */
#define COLS ROWS /* 10 x 10 */
int main (void) {
int arr[ROWS][COLS] = {{0}}, /* array holding random values 1-10 */
sum[ROWS][COLS] = {{0}}; /* array holding no. surrounding elements equal */
srand (time(NULL)); /* seed random number generator */
for (int i = 0; i < ROWS; i++) { /* loop filling array/output */
for (int j = 0; j < COLS; j++) {
arr[i][j] = rand() % 10 + 1;
printf (j ? " %3d" : "%3d", arr[i][j]);
}
putchar ('\n');
}
putchar ('\n');
for (int i = 0; i < ROWS; i++) { /* loop over each row */
for (int j = 0; j < COLS; j++) { /* loop over each col */
/* loop k from i-1 to i+1, use ternary to omit out of bounds checks */
for (int k = i ? i-1 : i; k <= ((i < ROWS - 1) ? i + 1 : i); k++) {
/* loop l from j-1 to j+1, user ternary to omit out of bounds checks */
for (int l = j ? j-1 : j; l <= ((j < COLS - 1) ? j + 1 : j); l++) {
/* if not comparing element to itself */
if (arr[i][j] == arr[k][l] && !(k == i && j == l))
sum[i][j] += 1; /* increment sum[i][j] */
}
}
}
}
puts ("\nNumber Surrounding Cells Equal (minesweeper format):\n");
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++)
if (sum[i][j])
printf (" %d ", sum[i][j]); /* if >= 1 output */
else
fputs (" ", stdout); /* otherwise output blank cell */
putchar ('\n');
}
示例使用/输出
$ ./bin/arr_edges_adj_equal
6 9 7 10 3 10 10 8 9 6
9 9 4 1 4 10 5 9 6 10
5 5 7 6 2 8 1 6 3 10
2 10 8 10 1 1 9 10 10 10
6 10 10 1 10 6 2 4 4 8
3 9 2 2 6 5 9 6 2 3
5 6 4 3 5 4 3 6 3 2
7 10 1 6 3 3 1 4 6 7
1 1 5 5 2 10 1 2 7 5
6 2 10 9 4 4 4 8 1 6
Number Surrounding Cells Equal (minesweeper format):
2 2 2 1 1
2 2 2 1 2 1
1 1 1 1 3
2 2 2 2 1 3 2
2 3 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 2 1 1
1 2 2 1 1 1
1 2 1 1 1 1
1 2 1
如果您还有其他问题,请仔细查看并告诉我。