我有以下方法在这种情况下显示数字的所有素数倍数20.我理解该方法的大多数递归行为,但是在打印数字5之后我有点困惑,为什么n又回来了在前一次调用中为5时(即执行第三个递归方法时)为10
public class Tester {
static boolean isPrime(int p)
{
for(int i = 2; i < p; i++)
{
if(p % i == 0) return false;
}
return true;
}
public static void primeFactors(int n)
{
primeFactorsR(n, n-1);
}
static int count1 = 1, count2 = 1, count3 = 1, count4 = 1;
public static void primeFactorsR(int n, int m)
{
if(isPrime(n))
{
System.out.println(n);
System.out.println("method1 " +count1++);
}
else
if(n % m == 0)
{
System.out.println("n " + n + " m " + m);
System.out.println("method2: " + count2++);
primeFactorsR(m, m-1);
System.out.println("n " + n + " m " + m);
System.out.println("method3: " + count3++);
primeFactorsR(n/m, (n/m)-1);
}
else
{
System.out.println("n " + n + " m " + m);
//System.out.println("n " + n + " m - 1 " + ( m-1));
System.out.println("method4: " + count4++);
primeFactorsR(n, m-1);
}
}
public static void main(String[] args) {
primeFactors(20);
}
}
输出
n 20 m 19
method4: 1
n 20 m 18
method4: 2
n 20 m 17
method4: 3
n 20 m 16
method4: 4
n 20 m 15
method4: 5
n 20 m 14
method4: 6
n 20 m 13
method4: 7
n 20 m 12
method4: 8
n 20 m 11
method4: 9
n 20 m 10
method2: 1
n 10 m 9
method4: 10
n 10 m 8
method4: 11
n 10 m 7
method4: 12
n 10 m 6
method4: 13
n 10 m 5
method2: 2
5
method1 1
n 10 m 5
method3: 1
2
method1 2
n 20 m 10
method3: 2
2
method1 3
BUILD SUCCESSFUL (total time: 1 second)
答案 0 :(得分:0)
我向控制台输出添加了更多信息,以使递归调用链可见
recursionLevel
显示递归的深度
每个primeFactorsR
- 函数调用都会收到唯一ID(请参阅funcId
- 变量)
函数id的序列创建了唯一的递归调用路径 - recursionPath
。
public class Tester {
static boolean isPrime(int p) {
for (int i = 2; i < p; i++) {
if (p % i == 0) return false;
}
return true;
}
public static void primeFactors(int n, int recursionLevel) {
primeFactorsR(n, n - 1, recursionLevel, null);
}
static int count1 = 1, count2 = 1, count3 = 1, count4 = 1;
private static int recursionId = 1;
public static void primeFactorsR(int n, int m, int recursionLevel, String recursionPath) {
int funcId = recursionId++;
if (recursionPath == null)
recursionPath = String.format("%s", funcId);
else
recursionPath = String.format("%s-%s", recursionPath, funcId);
if (isPrime(n)) {
System.out.println(String.format("n %s recursionLevel %s recursionPath %s", n, recursionLevel, recursionPath));
System.out.println("method1 " + count1++);
} else if (n % m == 0) {
System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
System.out.println("method2: " + count2++);
primeFactorsR(m, m - 1, recursionLevel + 1, recursionPath);
System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
System.out.println("method3: " + count3++);
primeFactorsR(n / m, (n / m) - 1, recursionLevel + 1, recursionPath);
} else {
System.out.println(String.format("n %s m %s recursionLevel %s recursionPath %s", n, m, recursionLevel, recursionPath));
//System.out.println("n " + n + " m - 1 " + ( m-1));
System.out.println("method4: " + count4++);
primeFactorsR(n, m - 1, recursionLevel + 1, recursionPath);
}
}
public static void main(String[] args) {
primeFactors(20, 1);
}
}
结果:
n 20 m 19 recursionLevel 1 recursionPath 1 method4: 1 n 20 m 18 recursionLevel 2 recursionPath 1-2 method4: 2 n 20 m 17 recursionLevel 3 recursionPath 1-2-3 method4: 3 n 20 m 16 recursionLevel 4 recursionPath 1-2-3-4 method4: 4 n 20 m 15 recursionLevel 5 recursionPath 1-2-3-4-5 method4: 5 n 20 m 14 recursionLevel 6 recursionPath 1-2-3-4-5-6 method4: 6 n 20 m 13 recursionLevel 7 recursionPath 1-2-3-4-5-6-7 method4: 7 n 20 m 12 recursionLevel 8 recursionPath 1-2-3-4-5-6-7-8 method4: 8 n 20 m 11 recursionLevel 9 recursionPath 1-2-3-4-5-6-7-8-9 method4: 9 n 20 m 10 recursionLevel 10 recursionPath 1-2-3-4-5-6-7-8-9-10 method2: 1 n 10 m 9 recursionLevel 11 recursionPath 1-2-3-4-5-6-7-8-9-10-11 method4: 10 n 10 m 8 recursionLevel 12 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12 method4: 11 n 10 m 7 recursionLevel 13 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13 method4: 12 n 10 m 6 recursionLevel 14 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14 method4: 13 n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15 method2: 2 n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16 method1 1 n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15 method3: 1 n 2 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-17 method1 2 n 20 m 10 recursionLevel 10 recursionPath 1-2-3-4-5-6-7-8-9-10 method3: 2 n 2 recursionLevel 11 recursionPath 1-2-3-4-5-6-7-8-9-10-18 method1 3
从结果中检查以下行:
n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15 method2: 2 n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16 method1 1 n 10 m 5 recursionLevel 15 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15 method3: 1
ID为15的函数,名为ID 16的函数,打印行:
n 5 recursionLevel 16 recursionPath 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16
之后,调用从16到15返回,函数15中的n
值仍为10
。
答案 1 :(得分:0)
这是因为在你的第二个if语句n % m == 0
中,它会对primeFactorsR
进行两次调用。第一个调用会引导您深入到堆栈中,其中5是素数。它然后返回堆栈,直到它到达它停止的位置,并在第二个打印语句上移动,给你第二个n 10 m 5.这是你的输出,它缩进每一层并打印出它在堆栈中的深度当它第一次进入primeFactorsR
并完成时。它向右前进的位置更深入到堆栈中,上面的层暂停。当图层完成处理后,它将返回上面的图层,如果该图层有更多要做,那么它将从它停止的位置继续。
We are the top layer
n 20 m 19
method4: 1
We are 1 layers deep
n 20 m 18
method4: 2
We are 2 layers deep
n 20 m 17
method4: 3
We are 3 layers deep
n 20 m 16
method4: 4
We are 4 layers deep
n 20 m 15
method4: 5
We are 5 layers deep
n 20 m 14
method4: 6
We are 6 layers deep
n 20 m 13
method4: 7
We are 7 layers deep
n 20 m 12
method4: 8
We are 8 layers deep
n 20 m 11
method4: 9
We are 9 layers deep
n 20 m 10
method2: 1
We are 10 layers deep
n 10 m 9
method4: 10
We are 11 layers deep
n 10 m 8
method4: 11
We are 12 layers deep
n 10 m 7
method4: 12
We are 13 layers deep
n 10 m 6
method4: 13
We are 14 layers deep
n 10 m 5
method2: 2
We are 15 layers deep
Prime 5
method1 1
Finished with layer 15
n 10 m 5
method3: 1
We are 15 layers deep
Prime 2
method1 2
Finished with layer 15
Finished with layer 14
Finished with layer 13
Finished with layer 12
Finished with layer 11
Finished with layer 10
n 20 m 10
method3: 2
We are 10 layers deep
Prime 2
method1 3
Finished with layer 10
Finished with layer 9
Finished with layer 8
Finished with layer 7
Finished with layer 6
Finished with layer 5
Finished with layer 4
Finished with layer 3
Finished with layer 2
Finished with layer 1
Finished