问题描述
用于计算n个自然数之和的函数
int solve(int n)
{
if(n==0 or n==1)
return n;
int sum=0;
sum=sum+n;
solve(n-1); // gives me wrong output
return sum;
}
int solve(int n)
{
if(n==0 or n==1)
return n;
int sum=0;
sum=sum+solve(n-1); // gives me correct output
return sum;
}
这两种功能在工作或输出方面有什么区别,因为调用栈在两种情况下均相同
解决方法
solve
函数在您的程序中没有任何作用
int solve(int n)
{
if(n==0 or n==1)
return n;
int sum=0;
sum=sum+n;
solve(n-1); // has not any effect
return sum;
}
在第二种方法中,返回值将始终为1,同时必须返回数字总和,用于计算数字总和的正确代码为:
int solve(int n)
{
if (n == 0 || n == 1)
return n;
int sum = 0;
sum = n + solve(n - 1); // change 'sum' with 'n'
return sum;
}
运行:
solve(5);
输出:
5 + 4 + 3 + 2 + 1 = 15
这两个功能有很多共同之处。
可以使用负参数调用函数,因为参数类型为int。在这种情况下,您将获得毫无意义的结果。
累积数字总和的变量的类型应大于int的类型,以免发生溢出。
第一个函数始终在函数的第一次递归调用中返回传递的参数的值。
此声明
solve(n-1); // gives me wrong output
无效,因为未使用返回值。
由于此语句,第二个函数始终返回0或1(前提是传递了非负参数)
if(n==0 or n==1)
return n;
因为此代码段
int sum=0;
sum=sum+solve(n-1); // gives me correct output
不使用参数的当前值。
似乎有错字,应该写
sum = n + solve(n-1); // gives me correct output
可以按照以下演示程序中所示的方式声明和定义该函数。
#include <iostream>
unsigned long long sum( unsigned int n )
{
return n == 0 ? 0 : n + sum( n - 1 );
}
int main()
{
std::cout << sum( 100 ) << '\n';
return 0;
}
程序输出为
5050
函数中的return语句也可以写成
return n < 2 ? n : n + sum( n - 1 );
要减少递归调用的次数,可以按以下方式重写函数
#include <iostream>
unsigned long long sum( unsigned int n )
{
return n < 2 ? n : sum( n - 2 ) + n + n - 1;
}
int main()
{
std::cout << sum( 100 ) << '\n';
return 0;
}