如何检查Java中调用递归函数的次数?

时间:2015-07-03 15:28:25

标签: java optimization recursion

假设递归函数,例如:

public static int factorial(int n){
    if(n==0){
        return 1;
    } else return n*factorial(n-1);
} 

我怎么知道为每个参数调用了多少次并将它们存储在map中? (即:n = 5次10次,n = 9次24次等)

编辑

假设目标是从这样的方法调用它,并且可以在程序中多次调用它:

public Map<Integer, Integer> getTheNumberOfOccasionsItHasBeenCalled();

3 个答案:

答案 0 :(得分:4)

当你返回1时,我想你可以做到

 StackTraceElement[] sts=Thread.currentThread.getStackTrace()

计算方法名称为factorial的所有StackTraceElement。

答案 1 :(得分:3)

对于你想要为每个可能的输入值调用递归次数的情况的基本解决方案(在阶乘的情况下,这是非常有用的,但在其他情况下可能是这样):

static int thenumberoftimesiwascalled;

public static int factorial(int n){
    thenumberoftimesiwascalled++;
    if(n==0){
        return 1;
    } else return n*factorial(n-1);
} 

...


Map<Integer,Integer> thenumberoftimeshewascalled = new HashMap<>();
for (int i=1;i+100;i++) {
   // reset counter
   thenumberoftimesiwascalled = 0;
   // calculate
   int result = factorial(i);
   System.out.println("called " + thenumberoftimesiwascalled + " times for " + i);
   // stash in Map
   thenumberoftimeshewascalled.put(i,result);
}

对地图做一些有用的事情留作练习,最小版本

static public Map<Integer, Integer> getNumberOfTimesCalled() {
   return thenumberoftimeshewascalled; 
}

其他解释,如果您只想计算外部调用函数的次数而不是递归次数:

Map<Integer,Integer> externalcallspervalue = new HashMap<>();

// the actual function, renamed to hide avoid you having to change 
// in all the places it was called:

private static int internalfactorial(int n){
    if(n==0){
        return 1;
    } else return n*factorial(n-1);
} 

// and a simple wrapper that does the accounting - and has the same name
// and signature of the original function.

public static int factorial(int n){
   // do the accounting
   Integer ntc = externalcallspervalue.get(i);
   if (ntc==null) { // first time we see this value
      ntc=1;
   } else {
      ntc += 1;
   }
   externalcallspervalue.put(i,ntc);
   // and return the result by calling the hidden internal function
   return internalfactorial(i);
}

现在

for (int i=1;i+100;i++) {
   int result = factorial(i);
}

每次调用一个值时,会给你1:1 2:1 3:1

答案 2 :(得分:2)

假设您有Map<Integer, Integer> map

public static int factorial(int n){
    if (map.containsKey(n)) {
        int times = map.get(n);
        map.put(n, times + 1);
    }
    else {
        map.put(n, 1);
    }

    if(n==0){
        return 1;
    } else return n*factorial(n-1);
} 

然后您可以随时查询地图以获取所需的值。 map.getOrDefault(5,0)返回调用方法的次数,其中n == 5或0如果方法没有被n == 5调用