[英]Memoization with recursive method in java
我正在做家庭作業,我已經筋疲力盡了。 我是編程新手,這是我的第一堂編程課。
這就是問題:
考慮 Collatz.java 中的以下遞歸函數,它與數論中一個著名的未解決問題有關,稱為 Collatz 問題或 3n + 1 問題。
public static void collatz(int n) {
StdOut.print(n + " ");
if (n == 1) return;
if (n % 2 == 0) collatz(n / 2);
else collatz(3*n + 1);}
例如,調用 collatz(7) 會打印序列 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 作為 17 次遞歸調用的結果。 編寫一個程序,接受命令行參數 N 並返回 n < N 的值,此時 collatz(n) 的遞歸調用次數最大化。 提示:使用記憶。 未解決的問題是沒有人知道函數是否對 n 的所有正值終止(數學歸納法沒有幫助,因為遞歸調用之一是針對更大的參數值)。
我嘗試了幾件事:使用 for 循環,嘗試使用每次執行方法時遞增的變量來計算執行次數,以及繁重的工作時間。
顯然,我應該在記憶中以某種方式使用數組。 但是,當必須在啟動時指定數組的長度時,我不明白如何使用數組。
我做錯了什么嗎? 我誤讀了這個問題嗎?
到目前為止,這是我的代碼。 它反映了嘗試創建整數數組的嘗試:
public class Collatz2 {
public static int collatz2(int n)
{
StdOut.print(n + " ");
if (n==1) {return 1;}
else if (n==2) {return 1;}
else if (n%2==0) {return collatz2(n/2);}
else {return collatz2(3*n+1);}
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
StdOut.println(collatz2(N));
}
}
編輯:
我寫了一個單獨的程序
public class Count {
public static void main(String[] args) {
int count = 0;
while (!StdIn.isEmpty()) {
int value = StdIn.readInt();
count++;
}
StdOut.println("count is " + count);
}
}
然后我使用了管道:%java Collatz2 6 | 計數
它工作得很好。
由於您對最大序列大小而不一定是序列本身感興趣,因此最好讓 collatz 返回序列的大小。
private static final Map<Integer,Integer> previousResults = new HashMap<>();
private static int collatz(int n) {
int result = 1;
if(previousResults.containsKey(n)) {
return previousResults.get(n);
} else {
if(n==1) result = 1;
else if(n%2==0) result += collatz(n/2);
else result += collatz(3*n + 1);
previousResults.put(n, result);
return result;
}
}
記憶是通過在 Map previousResults 中存儲之前 n 值的序列大小來實現的。
您可以在 main 函數中查找最大值:
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
int maxn=0, maxSize=0;
for(int n=N; n>0; n--) {
int size = collatz(n);
if(size>maxSize) {
maxn = n;
maxSize = size;
}
}
System.out.println(maxn + " - " + maxSize);
}
這里的技巧是編寫一個遞歸方法,其中參數是您想要“記憶”的值。 例如,這里有一個方法版本,它將返回達到 1 所需的步數(當然,它假設n
大於或等於 1):
public int countSteps(final int n)
{
return doCollatz(0, n);
}
public static int doCollatz(final int nrSteps, final int n)
{
if (n == 1)
return nrSteps;
final int next = n % 2 == 0 ? n / 2 : 3 * n + 1;
return doCollatz(nrSteps + 1, next);
}
如果你要記錄不同的步驟,你會傳遞一個List<Integer>
作為參數和.add()
在你經歷時傳遞給它,等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.