尾部递归java

尾部递归java,java,recursion,stack-overflow,tail-recursion,Java,Recursion,Stack Overflow,Tail Recursion,我正在寻找任何给定数的最大素因子。下面的代码适用于大多数数字,直到我输入我想要的数字600851475143为止。一旦我这样做,我就会得到堆栈溢出。我一直在阅读尾部递归,根据我所知道的,我应该正确地实现它。尽管如此,我仍然收到堆栈溢出错误。在实现尾部递归时,我哪里出了问题 import java.util.Scanner; public class LargestPrimeFactor { static long number; static long answer;

我正在寻找任何给定数的最大素因子。下面的代码适用于大多数数字,直到我输入我想要的数字600851475143为止。一旦我这样做,我就会得到堆栈溢出。我一直在阅读尾部递归,根据我所知道的,我应该正确地实现它。尽管如此,我仍然收到堆栈溢出错误。在实现尾部递归时,我哪里出了问题

import java.util.Scanner;
public class LargestPrimeFactor
{
    static long number;
    static long answer;

    public static void main(String[] args)
    {
        System.out.println( "Enter number to find its largest prime factor");
        Scanner input = new Scanner(System.in);
        number = input.nextLong();

        answer = largestPrime(number);
        System.out.println("The largest prime of " + number + " is " + answer);
    }

    private static long largestPrime(long n)
    {
        n = n-1;    
        if(n % 2 != 0 & number % n == 0 )
        {   
            return n;
        }
        else
        {           
            return largestPrime(n);
        }
    }
}

首先,在if条件下,您正在执行
&
,而您可能打算执行
&
。其次,您的实现是不正确的。试着在18上运行它(最大的素数是3),看看它返回的
9
显然不是素数

至于stackoverflow,由于没有限制
n>1的条件,因此在某些情况下,计算将继续
-1,-2,-3,…
,直到得到stackoverflow

最后,JVM不支持尾部递归优化,但即使它支持尾部递归优化,使用迭代解决方案也会更好,因为与递归解决方案不同,它不会为每个递归调用在堆栈上打开一个新框架(因为没有递归调用,它在循环中运行)

编辑

  • 要找到最大的素因子,可以从
    n/2
    开始,然后向下搜索 (每次迭代减去一次)
  • 素数
    p
    的定义是:
    p>1
    p
    只能被自身(和
    1
    )除。使用此定义并编写一个迭代方法
    boolean isPrime(int num)
  • 现在,使用前面的两个要点,并结合它们编写一个递归方法来查找最大素数。我不想为了不破坏你的乐趣而实施它:)

虽然Java确实支持尾部递归调用,但我不认为它目前优化了它们。你可以考虑使用。你做的很好,但是java编译器没有优化尾部调用进入一个循环,这不是旧的堆栈框架被新的一个覆盖的尾部递归的点吗?我可以看到它效率较低,因为必须执行更多的写入才能获得“干净”的框架(我不确定这是真的,我缺乏专业知识)。但是说它“打开一个新的帧”似乎不准确,除非它真的需要重置所有内容。是的,我正在运行一个迭代实现,但我注意到计算最终的数字需要一段时间。剩下两个问题。在什么时候我实现错了,所以它给出了9,这不是素数。另外,你有什么建议可以让它计算得更快?@ChrisHayes对方法的任何调用都会在堆栈上打开一个新的框架,即使进行优化,你也无法摆脱它所需要的“推送”和“弹出”。如果你想好好阅读这一主题:@SEV19957,我会再加一段。@alfasin是的,这正是我需要的。我根本不在乎欧拉计划的电话号码。整个原因是通过创造它的过程来学习,并促使自己去理解它。感谢您为我保存了实现的有趣部分:)