[英]I'm trying to sum up the numbers in a given array, using recursion , tried this code but it isn't working. Why?
#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“数组不为空”,将第一个元素求和,然后调用function,将数组的大小减1,对新数组进行sumByRecursion。
您需要将数组的大小传递给sumByRecursion
例程。
您需要传递数组大小的原因是因为数组不跟踪自己的大小。
像std::array
和std::vector
这样的替代方案提供了查询它们的大小的能力,但是 C 风格的 arrays 不携带该信息。
std::size
function 查询类型(在该上下文中是 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";
}
一个(可悲的)常见错误:
int sumByRecursion( int arr[] )
{ // What do you think ^^^^^ this is?
int n = sizeof(arr)/sizeof(arr[0]);
// ^^^^^^^^^^^ Sorry, too late.
// ...
}
正如评论部分已经指出的那样
在 function 内部,参数
arr
已衰减为 int* 类型,并且对数组中的元素数量一无所知。 ( 理查德克里顿)
简而言之:
int sumByRecursion( int arr[])
与int sumByRecursion( int *arr)
完全相同。 参数列表中的[]
语法只不过是语法糖。 ( 保罗麦肯齐)
解决方案是将大小与指针一起传递,或者明确地作为单独的 function 参数或在 object 中,如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
}
只是为了好玩(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) 说真的,不要使用这个。 这是完全低效和无用的复杂。 请改用正确的算法。
我可以使用算法Depth first search提供您问题的解决方案。
#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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.