Создание функции для проверки наличия смежных равных элементов в 2D-массиве в C

#c

#c

Вопрос:

Мне необходимо создать код, который принимает 2D-массив, а затем отправляет его в другую функцию, которая проверяет, есть ли смежные равные элементы по строке или столбцу или по или по диагностической строке, и подсчитывает их, область поиска каждого элемента сужается до 1, поэтому каждый элемент проверяет 8 элементоввозведение в квадрат и ничего сверх этого, у кого-нибудь есть идея, как это сделать? я попытался добавить некоторое условие if, но, похоже, ничего не работало, и счетчик оставался на 0 p.s я оставил 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", amp;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;
}
    ```
 

Комментарии:

1. Вы можете проверить 8 соседей, КРОМЕ where row == 0 или col == 0 или col == cols - 1 или row == rows - 1 . В этих особых случаях вы можете проверять только соседей, которые находятся внутри массива (а не за его пределами). Для диагонали применяется тот же предел, но вы проверяете только когда i == j .

2. Попробуйте этот метод. Вам нужно вызвать ее вместо вашего if, она возвращает количество равных ячеек для указанной ячейки.

3. Вы обводите, обрезаете, расширяете, обнуляете и т. Д. Свои края?

Ответ №1:

Если вы все еще застряли, как упоминалось в комментарии выше, то, что вы хотите сделать, это перебрать каждую строку и столбец и проверить доступные соседи на равенство. Сложность заключается в ограничении поиска всех 8-соседей, когда текущий индекс находится на краю или в углу. Например, ваши 2D-массивы имеют размеры ROWS x COLS , и вы выполняете цикл:

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

Вы находитесь на верхнем и нижнем краях в i == 0 and i == ROWS-1 , а также на левом и правом краях в j == 0 and j == 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 . Таким образом, с помощью внутренних циклов выше вы можете ограничить диапазон для каждого из циклов от i до i 1 if i == 0 и от i-1 до i if 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] amp;amp; !(k == i amp;amp; j == l))
                        sum[i][j]  = 1;     /* increment sum[i][j] */
                }
            }
        }
    }
 

(примечание: троичный используется как для инициализации количества циклов, так и для установки предела цикла для каждого из циклов)

Полный пример, который генерирует массив размером 10×10 со случайными значениями 1-10 , выводит массив, а затем проверяет соседей с помощью приведенной выше логики, а затем выводит результаты в формате Minesweeper из-за отсутствия лучших слов, где каждая ячейка содержит количество эквивалентных соседей, окружающих ее, выводя пустое значение sell, если их нет.равные соседи, например

 #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 ? " =" : "=", 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] amp;amp; !(k == i amp;amp; 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
 

Просмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.