递归函数采用两个相同大小的矩阵并输出它们是否相等

时间:2018-11-16 15:32:30

标签: c++ recursion

我正在尝试编写一个递归函数,该函数采用2个相等大小的矩阵,如果相等则返回1,否则返回0。

int equal(int[][3], int[][3], int, int);
int main()
{
    int matrixOne[3][3] = { { 1, 2, 8 }, { 3, 4, 9 }, { 3, 3, 3 } };
    int matrixTwo[3][3] = { { 1, 2, 8 }, { 3, 4, 9 }, { 3, 3, 3} };
    cout << equal(matrixOne, matrixTwo, 2, 2);
    system("pause");
    return 0;
}
int equal(int matrixOne[][3], int matrixTwo[][3], int row, int column)
{
    if (row < 0)
        return 1;
    if (column < 0)
    {
        column = row;
        row--;
    }
    if (matrixOne[row][column] == matrixTwo[row][column])
        return equal(matrixOne, matrixTwo, row, column - 1);
    else
    {
        return 0;
    }
}

它不应该工作,因为一旦列数达到零,我们就必须将其重置为原始的最大列数,这可以通过使column = row第一次完成。但是之后,它并不会遍历所有矩阵。

使用此函数原型甚至可以解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

您的功能可以使用,但是我必须做一些更改:

  1. column = row替换column = 2。请注意,在提供的代码中的函数参数中,矩阵被声明为matrixOne[][3]。由于3在第二维中,因此我不得不将2分配给列。要使该函数通用,您将不得不更改代码。

  2. 在列检查之后放置row < 0的检查。经过一些调试,您可以找出原因。如果不这样做,递归将不会在预期的点停止。

这是修改后的代码:

int equal(int[][3], int[][3], int, int);
int main()
{
    int matrixOne[3][3] = { { 1, 2, 8 }, { 3, 4, 9 }, { 3, 3, 3 } };
    int matrixTwo[3][3] = { { 1, 2, 8 }, { 3, 4, 9 }, { 3, 3, 3} };
    cout << equal(matrixOne, matrixTwo, 2, 2);
    system("pause");
    return 0;
}
int equal(int matrixOne[][3], int matrixTwo[][3], int row, int column)
{
    if (column < 0)
    {
        column = 2;
        row--;
    }
    if (row < 0)
        return 1;
    if (matrixOne[row][column] == matrixTwo[row][column])
        return equal(matrixOne, matrixTwo, row, column - 1);
    else
    {
        return 0;
    }
}

这是我测试代码的链接:https://ideone.com/4tBpJg

答案 1 :(得分:0)

You can easily make a generic version that allows matrices with any number of dimensions of any size of any type. You can make the size of the array a template parameter so that you don't have to pass it in.

#include <type_traits>
#include <cstddef>

template<class T, std::size_t N>
typename std::enable_if<!std::is_array<T>::value, bool>::type
equal(T (&a)[N], T (&b)[N]) {
    for (std::size_t i = 0; i < N; ++i) {
        // T is not an array, (a is a single dimension array)
        // so just compare the values.
        if (a[i] != b[i]) {
            return false;
        }
    }
    return true;
}

template<class T, std::size_t N>
typename std::enable_if<std::is_array<T>::value, bool>::type
equal(T (&a)[N], T (&b)[N]) {
    for (std::size_t i = 0; i < N; ++i) {
        // T is an array (So a is a multidimensional array)
        // recursively call the "equal" function on the
        // lower dimensional arrays.
        if (!equal(a[i], b[i])) {
            return false;
        }
    }
    return true;
}

For example:

#include <iostream>

int main() {
    // Modified the size so you can see it better
    int matrixOne[2][3] = { { 1, 2, 8 }, { 3, 4, 9 } };
    int matrixTwo[2][3] = { { 1, 2, 8 }, { 3, 4, 9 } };

    /*
    equal(matrixOne, matrixTwo)
    // bool equal<int[3], 2> equal(int[3][2], int[3][2]);
        is equivalent to:
    equal(matrixOne[0], matrixTwo[0]) && equal(matrixOne[1], matrixTwo[1])
    // bool equal<int, 3> equal(int[3], int[3]);
        And they just compare the 3 values per column
    */

    // prints 1
    std::cout << equal(matrixOne, matrixTwo) << '\n';
}

But, since the functions are just a multidimensional array of "int"s, you can just std::memcmp.

#include <type_traits>
#include <cstddef>
#include <cstring>

// Change the above to
template<class T, std::size_t N>
typename std::enable_if<
    !std::is_array<T>::value && !std::is_trivially_copyable<T>::value, bool
>::type
equal(T (&a)[N], T (&b)[N]);

template<class T, std::size_t N>
typename std::enable_if<
    std::is_array<T>::value && !std::is_trivially_copyable<T>::value, bool
>::type
equal(T (&a)[N], T (&b)[N]);

// And the new one for trivial types
template<class T, std::size_t N>
typename std::enable_if<std::is_trivially_copyable<T>::value, bool>::type
equal(T (&a)[N], T (&b)[N]) noexcept {
    return std::memcmp(a, b, sizeof(a)) == 0;
}