递归-C++的问题
problems with Recursion - C++
给定一个自然数n(1<=n<=500000),请输出其所有适当除数的总和。
定义:自然数的适当除数是指严格小于该数的除数。
例如,数字20有5个适当的除数:1、2、4、5、10,并且除数总和为:1+2+4+5+10=22。<lt--这是我正在尝试做的一个挑战,我正在使用递归
int find_sum(std::vector <int> nums,long int sum,int num_now,long int j)
{
if(j<nums[num_now])
{
if(nums[num_now]%j==0)
{
sum=sum+j;
}
return find_sum(nums,sum,num_now,j+1);
}
else
{
return sum;
}
}
sum是所有除数的和,nums是我存储数字的向量,num_now是向量中的当前成员,int j是1,我用它来搜索除数,遗憾的是,使用这个我不能使用500000这样的数字,这给我带来了错误,有更好的方法吗,或者我在某个地方犯了错误。
--感谢您抽出时间
这里有一种递归方法来解决您的问题:
int find_sum(int x, int i)
{
if(i == 0)
return 0;
if(x % i == 0)
return i + find_sum(x, (i-1));
return find_sum(x, (i-1));
}
您需要调用find_sum(N, N-1);
才能找到N的除法器之和(由于严格的不等式,i
必须小于给定的N
)。
在您的情况下,它将是find_sum(20, 19);
例如,我的函数返回:
71086
用于N = 50000
22
用于N = 20
0
用于N = 1
我看不出为什么需要使用递归来解决这个问题。我更喜欢一种更稳妥的方法来解决这个问题
long CalculateSumOfDivisors(int number)
{
long sum = 0;
for(int i=1; i<number; i++)
{
// If the remainder of num/i is zero
// then i divides num. So we add it to the
// current sum.
if(number%i==0)
{
sum+=i;
}
}
return sum;
}
此外,如果我们注意到以下内容,我们可以编写一个更优化的算法:
设我们有一个数n,d是n的最小除数,大于1。(显然,如果数字n是素数,那么就存在这样的除数)。那么n的最大除数就是数字n/d
基于此,我们可以制定一个更优化的算法。
long CalculateSumOfDivisors(int number)
{
int smallestDivisor = FindSmallestDivisor(number);
if(smallestDivisor==1) return 1;
long sum = smallestDivisor;
// Calculate the possible greatest divisor.
int possibleGreatestDivisor = (int)floor(number/smallestDivisor);
for(int i=smallestDivisor+1; i<=possibleGreatestDivisor; i++)
{
if(number%i==0)
{
sum+=i;
}
}
return sum;
}
int FindSmallestDivisor(int number)
{
int smallestDivisor = 1;
for(int i=2; i<number; i++)
{
if(number%i==0)
{
smallestDivisor = i;
break;
}
}
return smallestDivisor;
}
我试着用main函数编写代码,要求用户给出它想要得到的和。这是代码,希望能有所帮助。
#include<iostream>
using namespace std;
int Sum(int min, int max, int &val, int &sum){
if(min >= max)
return 0;
for ( ; min < max; min++){
if ( val%min == 0){
sum += min + val/min;
return Sum(++min,val/min, val,sum);
}
}
return 0;
}
int main(){
int s=1;
int val;
cout <<"Enter Val to sum:";
cin >> val;
Sum(2,val,val,s);
cout <<"Sum is :"<<s<<endl;
return 0;
}
这里,Sum函数是递归使用的,并传递代码中所示的参数。
希望能有所帮助。
我认为不应该使用递归。
相反,从1..N-1 开始循环
找到除数后,调整循环的结束值。例如,如果2是除数,那么你知道N/2也是除数。同样重要的是,你知道在这个范围内不可能有更多的除数。同样,如果3是除数,那么你知道N/3也是除数,你知道这个范围内不再有除数
根据这个概念,你可以显著减少大多数数字的循环次数。
类似于:
long find_sum(int num)
{
long sum = 0;
int max = num;
int i = 1;
while(i < max)
{
if(num % i == 0)
{
sum += i; // Add i to the sum
max = num / i; // Decrement max for performance
if (max != i && max != num)
{
sum += max; // Add max when max isn't equal i
}
}
i++;
}
return sum;
}
示例:
num = 10
sum = 0
i = 1 -> sum = 1, max = 10
i = 2 -> sum = 1+2+5, max = 5
i = 3 -> sum = 1+2+5, max = 5
i = 4 -> sum = 1+2+5, max = 5
i = 5 -> return 8 (1+2+5)
num = 64
sum = 0
i = 1 -> sum = 1, max = 64
i = 2 -> sum = 1+2+32, max = 32
i = 3 -> sum = 1+2+32, max = 32
i = 4 -> sum = 1+2+32+4+16, max = 16
i = 5 -> sum = 1+2+32+4+16, max = 16
i = 6 -> sum = 1+2+32+4+16, max = 16
i = 7 -> sum = 1+2+32+4+16, max = 16
i = 8 -> sum = 1+2+32+4+16+8, max = 8
i = 9 -> return (1+2+32+4+16+8)
每当发现新的除数时,通过改变max
来减少循环的数量。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用mongocxx驱动程序时包含头文件问题