我试图总结给定数组中的数字,使用 recursion ,尝试了这段代码,但它不起作用。为啥?
Posted
技术标签:
【中文标题】我试图总结给定数组中的数字,使用 recursion ,尝试了这段代码,但它不起作用。为啥?【英文标题】:I'm trying to sum up the numbers in a given array, using recursion , tried this code but it isn't working. Why?我试图总结给定数组中的数字,使用 recursion ,尝试了这段代码,但它不起作用。为什么? 【发布时间】:2022-01-18 19:53:54 【问题描述】:#include <iostream>
using namespace std;
int sumByRecursion( int arr[])
int sum = 0;
int n = sizeof(arr)/sizeof(arr[0]);
//n is the size of the array
if (n == 0)
return sum;
else
n -= 1;
for (int i=0;i=n;++i)
arr[i]=arr[i+1];
return (sum + arr[0] + sumByRecursion( arr));
int main()
int arr[]=2, 4, 6;
sumByRecursion( arr);
return 0;
sumByRecursion 基于这个想法工作: 1-如果数组的大小为0“空数组”,则返回总和。 2-如果大小不为0“数组不为空”,对sum的第一个元素求和,然后调用函数,将数组的大小减1,对新数组进行sumByRecursion。
【问题讨论】:
int n = sizeof(arr)/sizeof(arr[0]);
无法按您希望的方式工作。在函数内部,参数arr
已衰减为类型int*
,并且对数组中的元素数量一无所知。
看来您正在使用int n = sizeof(arr)/sizeof(arr[0]);
来确定数组的大小。这不计算数组的大小。可能是一个错误。
int arr[]=2, 4, 6;
--> std::array<int, 3> arr = 2,4,6;
然后使用 arr.size()
而不是您现在使用的来确定元素的数量(如上所述,这是错误的)。
对于应该是简单循环的代码是否需要使用递归?如果是这样,你有我的同情。无论如何,不要删除第一个元素,只需指向下一个元素。删除for
循环,对于递归调用,使用sumByRecursion(arr + 1)
。而且,正如其他 cmets 所指出的,您应该将数组的大小作为参数传递。
另外请注意,您使用的不是函数提供的结果。
【参考方案1】:
您需要将数组的大小传递给sumByRecursion
例程。
之所以需要传递数组的大小,是因为数组不跟踪自己的大小。
std::array
和 std::vector
等替代方法提供了查询它们的大小的功能,但 C 样式的数组不携带该信息。
std::size
函数查询 type(在该上下文中是 C 风格的数组)以计算大小。一旦作为int arr[]
参数传递,arr
类型就是int*
,它不再能够产生大小信息。
int arr[]
参数是int* arr
的一种写法,但建议读者arr
参数是一个C 风格的数组。可以被认为是自记录代码,如果正确完成 - 但许多程序会将参数表示为 int* arr
所以,唉,它不是一个普遍的习惯用法。
#include <cstddef>
#include <iterator>
#include <iostream>
using std::cout;
using std::size;
using std::size_t;
namespace
int sumByRecursion(int arr[], size_t n)
if (n == 0)
return 0;
else
// Many C++ compilers do not perform tail recursion optimization.
// But for those that do, this will thwart tail recursion optimization.
return arr[0] + sumByRecursion(arr+1, n-1);
// anon
int main()
int arr[] = 2, 4, 6;
auto arr_size = size(arr);
auto sum = sumByRecursion(arr, arr_size);
cout << sum << "\n";
【讨论】:
真的我觉得你应该提一下你需要传递尺寸的乳清。【参考方案2】:一个(可悲的)常见错误:
int sumByRecursion( int arr[] )
// What do you think ^^^^^ this is?
int n = sizeof(arr)/sizeof(arr[0]);
// ^^^^^^^^^^^ Sorry, too late.
// ...
正如评论部分已经指出的那样
在函数内部,参数
arr
已衰减为 int* 类型,并且对数组中元素的数量一无所知。 (Richard Critten)
简而言之:
int sumByRecursion( int arr[])
与int sumByRecursion( int *arr)
完全相同。参数列表中的[]
语法只不过是语法糖。 (PaulMcKenzie)
解决方案是将大小与指针一起传递,或者显式地作为单独的函数参数传递,或者在 std::span
或 std::ranges::range
等对象内部传递。
当然,另一种方法是传递 std::cbegin() 和 std::cend() 返回的两个迭代器。
用于“将数组的大小减少1”的代码可能是同样的误解:
int sum = 0;
// ...
if (n == 0) // Ok...
return sum;
else
n -= 1; // Okayish...
for (int i=0;i=n;++i) //
arr[i]=arr[i+1]; // <-- There's NO need to do all those copies!
//
return (sum + arr[0] + sumByRecursion( arr));
// ^^^^ This does NOT pass an array
Eljay 的answer 展示了如何正确实现 OP 的算法。
只是为了好玩(1),一个堆栈友好的实现
#include <iostream>
int sumByRecursion(size_t n, int const* arr)
// Stop the bloody recursion
if ( n == 0 )
return 0;
if ( n == 1 )
return arr[0];
// Divide et impera
size_t middle = n / 2;
return sumByRecursion(middle, arr)
+ sumByRecursion(n - middle, arr + middle);
int main()
int arr[] 2, 4, 6;
std::cout << sumByRecursion(std::size(arr), arr) << '\n';
(1) 说真的,不要使用这个。这是完全低效和无用的复杂。请改用正确的algorithm。
【讨论】:
【参考方案3】:我可以使用算法深度优先搜索为您的问题提供解决方案。
#include <iostream>
#include <vector>
using namespace std;
const int maximumSize=10;
vector<int> visited(maximumSize, 0);
int dfs(int current, int previous, vector<int>& input)
if(visited[current]==1)
return 0;
visited[current]=1;
int summarize=0;
for(int next=(current+1); next<input.size(); ++next)
if(next==previous)
continue;
summarize+=dfs(next, current, input);
summarize+=input[current];
return summarize;
void solve()
vector<int> inputVector=2, 4, 6;
cout<<dfs(0, -1, inputVector);
return;
int main()
solve();
return 0;
结果如下:
12
【讨论】:
以上是关于我试图总结给定数组中的数字,使用 recursion ,尝试了这段代码,但它不起作用。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
汇编代码返回数组中的最小整数,而不是随机返回最后一个或倒数第二个数字
快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值