我正在尝试编写一个递归函数,该函数采用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第一次完成。但是之后,它并不会遍历所有矩阵。
使用此函数原型甚至可以解决这个问题吗?
答案 0 :(得分:0)
您的功能可以使用,但是我必须做一些更改:
用column = row
替换column = 2
。请注意,在提供的代码中的函数参数中,矩阵被声明为matrixOne[][3]
。由于3
在第二维中,因此我不得不将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;
}