在Java中使用递归的推理因素

时间:2015-05-14 09:02:41

标签: java algorithm recursion primes prime-factoring

我在java中遇到了递归问题。所以我有以下方法,我应该只使用没有任何循环的递归来转换它。

public static List<Integer> primesLoop(int n) {
    List<Integer> factors = new ArrayList<Integer>();
    int f = 2;
    while (f <= n)
        if (n % f == 0) {
            factors.add(f);
            n /= f;
        } else
            f++;
    return factors;
}

递归方法应该以相同的形式开始:

public static List<Integer> primesRec(int n);

我还应该为转换定义帮助方法 结果是例如:

primesRec(900) -> prime factors of 900 : [2, 2, 3, 3, 5, 5]

2 个答案:

答案 0 :(得分:2)

您经常可以使用从循环形式到递归形式的简单变换。通常必须将局部变量移动到参数中。通常有两种形式,一种是提供用户界面,另一种是private,它们实际上执行递归功能。

public static List<Integer> primesLoop(int n) {
    List<Integer> factors = new ArrayList<Integer>();
    int f = 2;
    while (f <= n) {
        if (n % f == 0) {
            factors.add(f);
            n /= f;
        } else {
            f++;
        }
    }
    return factors;
}

public static List<Integer> primesRecursive(int n) {
    // The creation of factors and the start at 2 happen here.
    return primesRecursive(new ArrayList<>(), n, 2);
}

private static List<Integer> primesRecursive(ArrayList<Integer> factors, int n, int f) {
    // The while becomes an if
    if (f <= n) {
        // This logic could be tuned but I've left it as-is to show it still holds.
        if (n % f == 0) {
            factors.add(f);
            // Make sure either n ...
            n /= f;
        } else {
            // ... or f changes to ensure no infinite recursion.
            f++;
        }
        // And we tail-recurse.
        primesRecursive(factors, n, f);
    }
    return factors;
}

public void test() {
    for (int n = 10; n < 100; n++) {
        List<Integer> loop = primesLoop(n);
        List<Integer> recursive = primesRecursive(n);
        System.out.println("Loop     : " + loop);
        System.out.println("Recursive: " + recursive);
    }
}

注意两种方法之间的相似性。

答案 1 :(得分:0)

您可以通过重载添加f作为参数,并添加确实接受它的私有方法,并从“main”公共方法调用。

在私有方法中,您有3种情况:

  1. stop子句:n == 1:创建一个新的空列表
  2. n%f == 0:使用n'= n / f,f'= f进行递归,并将f添加到列表中。
  3. n%f!= 0:递归n'= n,f'= f + 1,不要在列表中添加任何内容。
  4. 代码:

    public static List<Integer> primesRecursive(int n) {
        return primesRecursive(n,2);
     }
    
     //overlaod a private method that also takes f as argument:
     private static List<Integer> primesRecursive(int n, int f) {
         if (n == 1) return new ArrayList<Integer>();
         if (n % f == 0) {
             List<Integer> factors = primesRecursive(n/f, f);
             factors.add(f);
             return factors;
         } else
             return primesRecursive(n,f+1);
     }
    

    正如预期的那样,调用:

    public static void main(String args[]) {
        System.out.println(primesRecursive(900));
    }
    

    将屈服:

    [5, 5, 3, 3, 2, 2]
    

    注意:如果您希望这些因子按升序排列:

    1. 在stop子句中将ArrayList实现切换为LinkedList(针对性能问题)
    2. 使用factors.add(0,f);而不是factors.add(f)
    3. 添加项目