在c中使用递归找到最大素因数
已经编写了我认为是一个很好的算法的代码,用于使用递归查找大量数字的最大素因数。不过,当分配给变量huge_number 的任何大于4 的数字时,我的程序都会崩溃。我不擅长递归,并且赋值不允许任何类型的循环。
#include <stdio.h>
long long prime_factor(int n, long long huge_number);
int main (void)
{
int n = 2;
long long huge_number = 60085147514;
long long largest_prime = 0;
largest_prime = prime_factor(n, huge_number);
printf("%ld\n", largest_prime);
return 0;
}
long long prime_factor (int n, long long huge_number)
{
if (huge_number / n == 1)
return huge_number;
else if (huge_number % n == 0)
return prime_factor (n, huge_number / n);
else
return prime_factor (n++, huge_number);
}
任何有关它为何崩溃以及我如何改进它的信息将不胜感激。
have wrote the code for what i see to be a good algorithm for finding the greatest prime factor for a large number using recursion. My program crashes with any number greater than 4 assigned to the variable huge_number though. I am not good with recursion and the assignment does not allow any sort of loop.
#include <stdio.h>
long long prime_factor(int n, long long huge_number);
int main (void)
{
int n = 2;
long long huge_number = 60085147514;
long long largest_prime = 0;
largest_prime = prime_factor(n, huge_number);
printf("%ld\n", largest_prime);
return 0;
}
long long prime_factor (int n, long long huge_number)
{
if (huge_number / n == 1)
return huge_number;
else if (huge_number % n == 0)
return prime_factor (n, huge_number / n);
else
return prime_factor (n++, huge_number);
}
any info as to why it is crashing and how i could improve it would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
即使解决了使用后递增的问题以使递归永远持续下去,这也不太适合递归解决方案 - 请参阅 这里了解原因,但归根结底是减少搜索的速度 空间。
虽然
huge_number
的除法很快就能减少它,但绝大多数递归调用都是通过简单地增加n
来完成的。这意味着您将使用大量的堆栈空间。你会更好:
(a) 这种野兽的一个示例(以递归解决方案为模型)是:
从该迭代解决方案的输出中可以看出,最大的因子是
10976461
。这意味着递归解决方案中的最后一批递归将需要一千万个堆栈帧的堆栈深度,这不是大多数环境能够轻松应对的。如果您确实必须使用递归解决方案,则可以利用您没有有一直检查这一事实,将堆栈空间减少到其平方根最多可达该数字,但仅限于其平方根。
此外,除了
2
之外,其他所有素数都是奇数,因此您可以通过仅检查两个加上奇数来进一步将搜索空间减半。考虑到这两件事的递归解决方案是:
您可以看到我还删除了(在我看来很尴尬)构造:
我更喜欢来自以下内容的不太大量缩进的代码:
但这只是个人喜好。无论如何,这会让你的递归级别降低到 1662(取消注释调试代码以进行验证)而不是 1000 万,这是一个相当大的减少,但仍然不完美。在我的环境下运行没问题。
Even fixing the problem of using post-increment so that the recursion continues forever, this is not a good fit for a recursive solution - see here for why, but it boils down to how fast you can reduce the search space.
While your division of
huge_number
whittles it down pretty fast, the vast majority of recursive calls are done by simply incrementingn
. That means you're going to use a lot of stack space.You would be better off either:
(a) An example of such a beast, modeled on your recursive solution, is:
As can be seen from the output of that iterative solution, the largest factor is
10976461
. That means the final batch of recursions in your recursive solution would require a stack depth of ten million stack frames, not something most environments will contend with easily.If you really must use a recursive solution, you can reduce the stack space to the square root of that by using the fact that you don't have to check all the way up to the number, but only up to its square root.
In addition, other than
2
, every other prime number is odd, so you can further halve the search space by only checking two plus the odd numbers.A recursive solution taking those two things into consideration would be:
You can see I've also removed the (awkward, in my opinion) construct:
I much prefer the less massively indented code that comes from:
But that's just personal preference. In any case, that gets your recursion level down to 1662 (uncomment the debug code to verify) rather than ten million, a rather sizable reduction but still not perfect. That runs okay in my environment.
您的意思是
n+1
而不是n++
。n++
使用后n
会递增 ,因此递归调用会获取n
的原始值。You meant
n+1
instead ofn++
.n++
incrementsn
after using it, so the recursive call gets the original value ofn
.您正在溢出堆栈,因为 n++ 后递增该值,使用与当前调用中相同的值进行递归调用。
You are overflowing stack, because n++ post-increments the value, making a recursive call with the same values as in the current invocation.
崩溃原因是堆栈溢出。我向您的程序添加一个计数器并执行它(在 ubuntu 10.04 gcc 4.4.3 上),计数器在核心转储之前停止在“218287”。更好的解决方案是使用循环而不是递归。
the crash reason is stack overflow. I add a counter to your program and execute it(on ubuntu 10.04 gcc 4.4.3) the counter stop at "218287" before core dump. the better solution is using loop instead of recursion.