【问题标题】:How to traverse a 2D array using recursion如何使用递归遍历二维数组
【发布时间】:2020-06-02 21:36:09
【问题描述】:

我正在寻找帮助我使用递归遍历和显示二维数组或矩阵的人。

void display(int** matrix1,int row, int column)

这就是我为一维数组所做的:

void print_array(int arr[], int size, int i)
{

    if (i == size) {
        cout << endl;
        return;
    }
    cout << arr[i] << " ";
    print_array(arr, size, i+1);
}

我知道如何遍历一维数组,但无法做到这一点。 我想使用递归显示矩阵中的每个元素。

【问题讨论】:

  • 对于初学者来说,您没有二维数组,并且不清楚您所说的“遍历”一词是什么意思。
  • « 我知道如何遍历一维数组 » FWIW,二维数组是一维数组的一维数组。
  • @VladfromMoscow 感谢您与我们联系。我的意思是说如何使用递归显示矩阵中的每个元素,因为我们只需使用 2 个 for 循环即可。
  • @hugo 是的,我知道,但在递归的情况下,我认为没那么简单。
  • @MuhammadAsim 也许是……您能否编辑答案以包括如何遍历“一维数组”?这将有助于理解并提供您正在寻找的解决方案

标签: c arrays function recursion definition


【解决方案1】:

首先,您需要递归解决方案的原因还不是很清楚。也许这是一个问题,但我发现递归很难编写、阅读和调试。无论如何,我允许自己修改您的 1d 版本:

#include <iostream>
#include <vector>

void print_array(const std::vector<int>& arr,size_t i = 0) {
    if (i == arr.size()) {
        std::cout << '\n';
        return;
    }
    std::cout << arr[i] << " ";
    print_array(arr, i+1);
}

我使用size_t 而不是int,因为这是与容器大小比较时要使用的类型。我为i 提供了一个默认值,因为当你调用它时你不想传递索引,而只是打印整个数组。 std::endl 不仅打印新行,而且还刷新流。在大多数情况下,这是不必要的。

对于 2D 情况,您只需添加第二个索引和进入下一行的条件。

也就是说,如果函数的签名是

void print_array(const std::vector<std::vector<int>>& arr,size_t i=0,size_t j=0)

它会打印arr[i][j],然后在i == arr.size() 时您需要返回而不打印任何内容,而在j== arr[i].size() 时您必须跳到下一行。这可以通过以下条件来完成:

    if (j == arr[i].size()) {
        std::cout << '\n';
        print_array( arr, i+1,0);  // start with the first element of next row
        return;
    }

PS你是否坚持使用int**,它应该很容易适应,但我强烈建议使用vector,如果内部数组全部使用,甚至可能使用std::vector&lt;std::array&gt;大小相同。

【讨论】:

  • OP想要使用递归的最可能原因是它是一种人为的约束(即练习)......
  • @hugo 是的,这是我能想到的唯一解释。不幸的是,我只有在写完答案后才有了这种洞察力,否则我就不会写了。运动被宠坏了,好可怜……
  • 我并不反对你提供完整的解决方案顺便说一句——如果问题/答案有用,那么我认为它们是合法的。
  • @hugo 不用担心,有时我喜欢回答这样 OP 可以自己解决而不是给出完整的解决方案。
【解决方案2】:

我确信您需要编写 C 程序或 C++ 程序,但由于您声明了“二维数组”,例如 int **.:)

如果再使用一个辅助的递归函数,该函数可以很容易实现。

这是一个演示程序

#include <stdio.h>

void display_row( int *a, size_t column )
{
    column == 0 ? ( void )putchar( '\n' )
                : ( void )( printf( "%2d ", *a ), display_row ( ++a, --column ) );
}

void display( int **a, size_t row, size_t column )
{
    if ( row != 0 )
    {
        display_row( *a, column );
        display( ++a, --row, column );
    }
}

int main(void) 
{
    enum { M = 3, N = 4 };

    int a1[N] = {  1,  2,  3,  4 };
    int a2[N] = {  5,  6,  7,  8 };
    int a3[N] = {  9, 10, 11, 12 };

    int *a[M] = { a1, a2, a3 };

    display( a, M, N );

    return 0;
}

程序输出是

 1  2  3  4 
 5  6  7  8 
 9 10 11 12 

如果不使用辅助函数,那么另一种方法是在递归函数中使用静态变量。

这是一个演示程序,它使用带有静态变量的递归函数。

#include <stdio.h>

void display( int** a, size_t row, size_t column )
{
    static size_t pos = 0;

    if ( row != 0 && column == 0 )
    {
        putchar( '\n' );
        size_t tmp = column;
        column = pos;
        pos = tmp;
        --row;
        ++a;
    }       

    if ( row )  
    {
        printf( "%2d ", a[0][pos++] );
        display( a, row, --column );
    }       
}

int main(void) 
{
    enum { M = 3, N = 4 };

    int a1[N] = {  1,  2,  3,  4 };
    int a2[N] = {  5,  6,  7,  8 };
    int a3[N] = {  9, 10, 11, 12 };

    int *a[M] = { a1, a2, a3 };

    display( a, M, N );

    return 0;
}

其输出与上图相同。

如果您需要 C++ 程序,则只需包含标题

#include <iostream>
#include <iomanip>

而不是例如这个 printf 调用

printf( "%2d ", a[0][pos++] );

使用

std::cout << std::setw( 2 ) << a[0][pos++];

【讨论】:

  • 完美。谢谢。
  • @VladfromMoscow Well OP 也使用了cout 和流操作符,所以我不太确定 C 是理想的语言。编辑,但无论如何,你的回答似乎有帮助
  • @hugo 用 printf 调用代替运算符并不难
  • 当然。我想我误读了你的第一句话......你肯定是想写“我确定你是否需要编写 C 程序或 C++ 程序”......无论如何,干杯:)
猜你喜欢
  • 2010-12-11
  • 2012-07-17
  • 2011-07-18
  • 2021-01-18
  • 1970-01-01
  • 2015-04-07
  • 2017-12-12
  • 2016-04-06
  • 2016-09-04
相关资源
最近更新 更多