首页 > 解决方案 > 在 C 中创建一个函数来检查二维数组中是否存在相邻的相等元素

问题描述

我需要创建一个代码,该代码采用二维数组,然后将其发送到另一个函数,该函数检查是否存在按行或按列或按诊断线或按诊断线的相邻相等元素并计算它们,每个元素的搜索区域是缩小到 1,所以每个元素都会检查 8 个元素的平方,除此之外什么都没有,有人知道怎么做吗?我尝试添加一些 if 条件,但似乎没有任何效果,并且计数器保持在 0 ps 我将 if() 留空,因为我尝试了很多条件,但没有一个有效这是我迄今为止想出的:

  #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define rows 2
#define columns 3
int MatrixCheck(int Matrix[rows][columns])
{
    int i = 0, j = 0;
    int Counter = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < columns; j++)
        {
            if ()
            {
                Counter++;
            }
        }

    }
    return Counter;
}
int Matrix()
{
    int Matrix[rows][columns];
    int i, j, Count = 0, Sum = 0;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < columns; j++)
        {
            printf("Enter Value For Place : [%d][%d]   ", i, j);
            scanf("%d", &Matrix[i][j]);
        }
    }
    printf("Matrix Display:  \n");
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < columns; j++)
        {
            Count++;
            printf("%d   ", Matrix[i][j]);
            if (Count % columns == 0)
            {
                printf("\n");
            }
        }
    }
}

int main()
{
    Matrix();
    MatrixCheck(Matrix);
    printf("Neighbores Count is %d .\n", MatrixCheck(Matrix));
    return 0;
}
    ```

标签: c

解决方案


如果您仍然卡住,如上面的评论中所述,您想要做的是遍历每一行和每一列并检查可用的邻居是否相等。当当前索引位于边缘或角落时,困难在于限制对所有 8 个邻居的搜索。例如,您的二维数组的维度为ROWS x COLS,并且您循环:

    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {

您在 和 处位于顶部和底部边缘,在和i == 0i == ROWS-1位于左侧和右侧边缘。您在 的上角和,的下角。j == 0j == COLS-1[0][0][0][COLS-1][ROWS-1][0][ROWS-1][COLS-1]

有两种方法可以限制对周围邻居的检查,以确保您不会检查数组边界之外的元素。您可以反复循环ij创建一组相当长的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

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


推荐阅读