簡體   English   中英

在Java中使用遞歸的主要因素

[英]Prime factors using recursion in Java

我在使用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]

您通常可以使用從循環形式到遞歸形式的簡單轉換。 通常必須將局部變量移至參數中。 通常有兩種形式,一種提供用戶界面,另一種通常是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);
    }
}

注意這兩種方法之間的相似性。

您可以通過重載來添加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遞歸,不向列表添加任何內容。

碼:

public static List<Integer> primesRecursive(int n) {
    return primesRecursive(n, 2);
 }

 //overload 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(0, f); 而是factors.add(f)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM