递归功能可根据条件搜索查找并更改特定的单元格

时间:2019-05-13 06:15:34

标签: c recursion

我正在尝试用C语言编写一个递归函数,该函数将NxM矩阵作为输入,并根据场景查找,检查特定单元格并更改其内容。

Original matrix

矩阵元素是:

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

根据上述矩阵,用户可以指定特定单元格的位置,例如整数2的位置(5,6)。我希望递归函数在四个方向上,向下,向左,向右检查单元格,以及是否找到相同的整数以将它们更改为0s。对于所有“邻居”单元,这将继续。在此示例中,位置(5,6),(5,5)和(4,5)的所有二进制将变为0。

另一个例子: 用户给出位置,即整数6的位置(8,7)。递归函数必须在位置(8,7),(7,7),(7,8),(7,6)处查找并更改所有6s ),(6,6),(6,8)并将其设置为0s。

    void destroy(int (*arr), int rows, int cols,int search,int rowin, int colin) //rows: total rows of matrxi, cols:total cols of matrix, rowin and colin are the x,y co ordinates of the cell that the user wants to destroy and search has the int i.e 6 ..
{
    int i, j;

    printf("\n");
    printf("\n");

    int count = 0,temp = 0;

    for (j = 0; j < cols; j++) {
    for (i = 0; i < rows; i++) {

          if (*(arr + i*cols + j)== search) {
          if (*(arr + (i-1)*cols + j) == search){//check neighborhood cell
            count++; //counter to know how many similar neighborhood integers have been found
            (*(arr + i*cols + j)= 0);
            *(arr + (i-1)*cols + j) = 0;    
            destroy(int (*arr), int rows, int cols,int search, j, i)   //call recursive function to check the neighborhood cells of the new position  i,j           

        }

      }     
}
}
}

3 个答案:

答案 0 :(得分:2)

您不需要for循环,而需要四个递归调用来检查每个邻域。

   void destroy(int *arr, int rows, int cols,int search,int rowin, int colin)
    {
         if (rowin>=rows || colin >= cols || rowin < 0 || colin <0) 
             return; //base condition

         if (arr[rowin*cols+colin] == search)
         {
              arr[rowin*cols+colin] = 0;
              destroy(arr, rows, cols, search, rowin+1, colin);
              destroy(arr,  rows, cols, search, rowin, colin+1);
              destroy(arr,  rows, cols, search, rowin-1, colin);
              destroy(arr,  rows, cols, search, rowin, colin-1);

         }
    }

答案 1 :(得分:1)

请注意,在C语言中,数组索引从零(不是一个)开始。

这是一个使用矩阵(又称数组数组)的示例。

#include <stdio.h>

void destroy(int value, int r, int c, int r_size, int c_size, int arr[][r_size])
{
    if (value != arr[r][c]) return;  // Nothing to do
    arr[r][c] = 0;
    if (r+1 < r_size) destroy(value, r+1, c, r_size, c_size, arr); // DOWN
    if (r-1 >= 0) destroy(value, r-1, c, r_size, c_size, arr);     // UP
    if (c+1 < c_size) destroy(value, r, c+1, r_size, c_size, arr); // RIGHT
    if (c-1 >= 0) destroy(value, r, c-1, r_size, c_size, arr);     // LEFT
}


void pm(int r_size, int c_size, int arr[r_size][r_size])
{
    printf("-------------------------------------------\n");
    for (int r=0; r < r_size; ++r)
    {
        for (int c=0; c < c_size; ++c)
        {
            printf("%d ", arr[r][c]);
        }
        printf("\n");
    }
}
#define MSIZE 8

int main(void) {
    int arr[MSIZE][MSIZE] =
    {
        {1, 6, 7, 4, 4, 1, 2, 8},
        {1, 3, 6, 3, 3, 1, 3, 4},
        {3, 4, 1, 5, 7, 8, 5, 1},
        {1, 7, 8, 6, 2, 6, 4, 4},
        {7, 8, 1, 6, 2, 2, 7, 1},
        {3, 8, 4, 3, 1, 6, 8, 6},
        {3, 8, 7, 5, 4, 6, 6, 6},
        {7, 2, 2, 1, 7, 4, 6, 8}
    };

    pm(MSIZE, MSIZE, arr);
    destroy(arr[7][6], 7, 6, MSIZE, MSIZE, arr);
    pm(MSIZE, MSIZE, arr);

    return 0;
}

输出:

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

版本2

此版本略有不同,因为它仅在找到至少一个邻居时才更改元素。此外,它还会计算更改次数。

#include <stdio.h>
#include <stdlib.h>

int destroy_rec(int value, int r, int c, int r_size, int c_size, int arr[][r_size])
{
    if (value != arr[r][c]) return 0;  // Nothing to do
    int changed = 1;
    arr[r][c] = 0;
    if (r+1 < r_size) changed += destroy_rec(value, r+1, c, r_size, c_size, arr); // DOWN
    if (r-1 >= 0) changed += destroy_rec(value, r-1, c, r_size, c_size, arr);     // UP
    if (c+1 < c_size) changed += destroy_rec(value, r, c+1, r_size, c_size, arr); // RIGHT
    if (c-1 >= 0) changed += destroy_rec(value, r, c-1, r_size, c_size, arr);     // LEFT
    return changed;
}

int destroy(int r, int c, int r_size, int c_size, int arr[][r_size])
{
    if (r+1 < r_size && arr[r+1][c] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
    if (r-1 >= 0 && arr[r-1][c] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
    if (c+1 < c_size && arr[r][c+1] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
    if (c-1 >= 0 && arr[r][c-1] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
    return 0;
}

void pm(int r_size, int c_size, int arr[r_size][r_size])
{
    printf("-------------------------------------------\n");
    for (int r=0; r < r_size; ++r)
    {
        for (int c=0; c < c_size; ++c)
        {
            printf("%d ", arr[r][c]);
        }
        printf("\n");
    }
    printf("-------------------------------------------\n");
}
#define MSIZE 8

int main(void) {
    int arr[MSIZE][MSIZE] =
    {
        {1, 6, 7, 4, 4, 1, 2, 8},
        {1, 3, 6, 3, 3, 1, 3, 4},
        {3, 4, 1, 5, 7, 8, 5, 1},
        {1, 7, 8, 6, 2, 6, 4, 4},
        {7, 8, 1, 6, 2, 2, 7, 1},
        {3, 8, 4, 3, 1, 6, 8, 6},
        {3, 8, 7, 5, 4, 6, 6, 6},
        {7, 2, 2, 1, 7, 4, 6, 8}
    };

    pm(MSIZE, MSIZE, arr);
    int changed = destroy(7, 6, MSIZE, MSIZE, arr);
    printf("%d cells changed\n", changed);
    pm(MSIZE, MSIZE, arr);

    int (*dyn_arr)[MSIZE] = malloc(MSIZE * sizeof *dyn_arr);
    return 0;
}

输出:

-------------------------------------------
1 6 7 4 4 1 2 8 
1 3 6 3 3 1 3 4 
3 4 1 5 7 8 5 1 
1 7 8 6 2 6 4 4 
7 8 1 6 2 2 7 1 
3 8 4 3 1 6 8 6 
3 8 7 5 4 6 6 6 
7 2 2 1 7 4 6 8 
-------------------------------------------
6 cells changed
-------------------------------------------
1 6 7 4 4 1 2 8 
1 3 6 3 3 1 3 4 
3 4 1 5 7 8 5 1 
1 7 8 6 2 6 4 4 
7 8 1 6 2 2 7 1 
3 8 4 3 1 0 8 0 
3 8 7 5 4 0 0 0 
7 2 2 1 7 4 0 8 
-------------------------------------------

答案 2 :(得分:0)

我不知道您想要实现什么,因为在您的代码中您已经遍历了整个数组,并且在检查了一个元素之后想再次遍历。 以我的观点,您不需要再次迭代即可删除元素。您可以在单个迭代中执行此操作。 如果要搜索的元素存在,则删除相邻元素 (i,j => (i-1,j : i+1,j : i,j-1 : i,j+1))
这样,您可能需要对索引值进行一些检查,以避免未定义的行为。