简体   繁体   English

我试图总结给定数组中的数字,使用递归,尝试了这段代码,但它不起作用。 为什么?

[英]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::arraystd::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 as int 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::spanstd::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.

相关问题 我不确定为什么这段代码不起作用? - I'm not sure why this code isn't working? 我正在制作一个简单的程序来计算矢量结果,但我不知道为什么它不起作用。 - I'm making a simple program to calculate vector resultants and I can't figure out why it isn't working. 我试图提出一个跨平台替代sleep()的方法,但是我的代码运行不正常 - I tried to come up with a cross platform alternative to sleep(), but my code isn't quite working 我正在尝试使用rand和rand获得数字1:16的随机顺序。 该代码可以按预期运行,但只能运行到第12次迭代。 - I'm trying to get a random order of numbers 1:16 using srand and rand. The code works as expected but only up to the 12th iteration.Why? 我的 C++ 合并排序代码不起作用。 我在这里缺少什么? - My C++ Merge Sort code isn't working. What am i missing here? c ++传递函数作为数组索引不起作用。 - c++ passing function as array index isn't working. 为什么我的 class 不使用我给它的值? - Why isn't my class using the values I've given it? 为什么循环这个数组时我的代码不能正常工作 - Why isn't my code working properly when looping this array 无法获取我的代码来正确排序用户输入的数字数组(使用递归) - Can't get my code to correctly sort user input array of numbers (using recursion) 无法弄清楚为什么我的开关不起作用。 似乎无法识别cin输入 - Can't figure out why my switch isn't working. Seems to not be recognizing the cin input
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM