[英]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 working based on this idea: 1-if the size of the array is 0 "empty array", return the sum. sumByRecursion 基于这个思想工作: 1-如果数组的大小为 0 “空数组”,则返回总和。 2-if size isn't 0 "array isn't empty", sum up the first element on sum, then call the function, reduce the array's size by 1, sumByRecursion on the new array. 2-如果大小不为0“数组不为空”,将第一个元素求和,然后调用function,将数组的大小减1,对新数组进行sumByRecursion。
You need to pass in the size of the array to the sumByRecursion
routine.您需要将数组的大小传递给sumByRecursion
例程。
The reason you need to pass the size of the array is because the array does not track its own size.您需要传递数组大小的原因是因为数组不跟踪自己的大小。
Alternatives like std::array
and std::vector
provide the capability of querying them for their size, but C-style arrays do not carry along that information.像std::array
和std::vector
这样的替代方案提供了查询它们的大小的能力,但是 C 风格的 arrays 不携带该信息。
The std::size
function queries the type (which is a C-style array in that context) to figure out the size. std::size
function 查询类型(在该上下文中是 C 样式数组)以计算大小。 Once passed as an int arr[]
parameter, that arr
type is int*
which no longer can produce the size information.一旦作为int arr[]
参数传递,该arr
类型就是int*
,它不再可以产生大小信息。
The int arr[]
parameter is a way of writing int* arr
, but suggests to the reader that the arr
parameter is a C-style array. int arr[]
参数是一种编写int* arr
的方式,但向读者建议arr
参数是 C 样式的数组。 Could be considered self-documenting code, when done correctly -- but many programs would express the parameter as int* arr
so, alas, it is not a widespread idiom.如果正确完成,可以将其视为自记录代码 - 但是许多程序会将参数表示为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";
}
A (sadly) common mistake:一个(可悲的)常见错误:
int sumByRecursion( int arr[] )
{ // What do you think ^^^^^ this is?
int n = sizeof(arr)/sizeof(arr[0]);
// ^^^^^^^^^^^ Sorry, too late.
// ...
}
As already noted in the comment section正如评论部分已经指出的那样
Inside the function the parameter
arr
has decayed to type int* and knows nothing about the number of elements in the array.在 function 内部,参数arr
已衰减为 int* 类型,并且对数组中的元素数量一无所知。 ( Richard Critten ) ( 理查德克里顿)
In short:
int sumByRecursion( int arr[])
is exactly the same asint sumByRecursion( int *arr)
.简而言之:int sumByRecursion( int arr[])
与int sumByRecursion( int *arr)
完全相同。 That[]
syntax in the parameter list is nothing more than syntax sugar.参数列表中的[]
语法只不过是语法糖。 ( PaulMcKenzie ) ( 保罗麦肯齐)
The solution is to pass the size alongside the pointer, either explicitly as a separate function argument or inside an object like std::span
or std::ranges::range
.解决方案是将大小与指针一起传递,或者明确地作为单独的 function 参数或在 object 中,如std::span
或std::ranges::range
。
An alternative, of course, is to pass the couple of iterators returned by std::cbegin() and std::cend() .当然,另一种方法是传递std::cbegin()和std ::cend() 返回的几个迭代器。
The code used to "reduce the array's size by 1" is probably a result of the same misunderstanding:用于“将数组的大小减少 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 's answer shows how to correctly implement OP's algorithm. Eljay的回答显示了如何正确实现 OP 的算法。
Just for fun (1) , a stack-friendlier implementation只是为了好玩(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) Seriously, do NOT use this. (1) 说真的,不要使用这个。 It's utterly inefficient and uselessly convoluted.这是完全低效和无用的复杂。 Use the right algorithm instead.请改用正确的算法。
I can offer the solution of your problem, using the algorithm Depth first search .我可以使用算法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;
}
Here is the result:结果如下:
12
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.