如何检查递归函数在Java中被调用了多少次?

如何检查递归函数在Java中被调用了多少次?,java,optimization,recursion,Java,Optimization,Recursion,假设一个递归函数,例如: public static int factorial(int n){ if(n==0){ return 1; } else return n*factorial(n-1); } 如何知道每个参数调用了多少次并将其存储在映射中?i、 e:n=5时为10次,n=9时为24次等 编辑: 假设目标是从这样的方法调用它,并且可以在程序中多次调用它: public Map<Integer, Integer> getTheNumber

假设一个递归函数,例如:

public static int factorial(int n){
    if(n==0){
        return 1;
    } else return n*factorial(n-1);
} 
如何知道每个参数调用了多少次并将其存储在映射中?i、 e:n=5时为10次,n=9时为24次等

编辑:

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

public Map<Integer, Integer> getTheNumberOfOccasionsItHasBeenCalled();

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

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

并计算方法名为阶乘的所有StackTraceeElement。

当您返回1时,我想您可以这样做

 StackTraceElement[] sts=Thread.currentThread.getStackTrace()
并计算方法名称为阶乘的所有StackTraceElement。

假设您有Map

然后,您可以随时查询地图以获取所需的值。map.getOrDefault5,0返回调用该方法的次数(其中n==5),或者如果该方法未在n==5时调用,则返回0(假设您有map map)


然后,您可以随时查询地图以获取所需的值。map.getOrDefault5,0返回在n==5时调用方法的次数,或者如果没有在n==5时调用方法,则返回0。对于要调用每个可能输入值的递归次数的情况,基本解决方案在阶乘的情况下不太有用,但在其他情况下可能有用:

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);
}

将为您提供1:1 2:1 3:1,因为每个值只调用了一次。

对于要为每个可能的输入值调用递归次数的情况,基本解决方案在阶乘的情况下不太有用,但在其他情况下可能有用:

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);
}


将为您提供1:1 2:1 3:1,因为每个值调用了一次。

n=5时调用了10次,n=9时调用了24次等等。您的意思是函数调用了这么多次吗??“我不这么认为……”Codebender我没有说过,从来没有。这是一个假设的例子,你可以检查stackTrace,或者简单地在你的方法中添加一个标志,对n=5的调用数进行10次计数,对n=9的调用数进行24次计数等等,你是说函数被调用了这么多次吗??“我不这么认为……”Codebender我没有说过,从来没有。这是一个假设的例子,你可以检查stackTrace,或者简单地在你的方法中添加一个标志来计算调用数这是错误的。。。如果调用factorial5,映射将有5个从1到5的键,每个键的值为1。我不认为这是OP想要的…有可能我误解了这个问题这是错误的。。。如果调用factorial5,映射将有5个从1到5的键,每个键的值为1。我不认为那是OP想要的…我可能误解了question@stackpepe所以现在你不需要函数递归的次数,而是初始调用的次数???。我的意思是,执行阶乘5;因子5;结果会是5:2吗?我仍然想要相同的结果,目标是检查为不同的值调用了多少次,并将其存储在地图中。例如,你可以调用factorial4,factorial10,factorial20,你可以存储每个函数调用的次数。@stackpepe我们显然在不同的波长上:在你的例子中,你想这样做吗参见4:110:120:1,即,从外部调用函数的次数或获得每个输入值的结果所需的递归次数。后者是我解决的问题,但我不确定这是否是你想要的。首先,如果我之前不清楚,我很抱歉,但我想得到的是为映射中的每个输入值获得结果所需的递归次数。但是,它将使用我编写的方法从外部调用。在方法中添加注释以获得更好的效果understanding@stackpepe在这种情况下,我认为我的原始代码满足您的需要。为了更好地排序,我还添加了第二个似乎合理的情况,即,考虑从外部调用阶乘的次数。你同意第一个代码给出你需要的结果吗?@stackpepe所以现在你不需要函数递归的次数,而是初始调用的次数???。我的意思是,执行阶乘5;因子5;结果会是5:2吗?我仍然想要相同的结果,目标是检查为不同的值调用了多少次,并将其存储在地图中。例如,你可以调用factorial4,factorial10,factorial20,你可以存储每个函数调用的次数。@stackpepe我们显然在不同的波长上:在你的例子中,你想这样做吗参见4:110:120:1,即,从外部调用函数的次数或获得每个输入值的结果所需的递归次数。后者是我解决的问题,但我不确定这是否是你想要的。首先,如果我之前不清楚,我很抱歉,但我想得到的是为映射中的每个输入值获得结果所需的递归次数。但是,它将使用我编写的方法从外部调用。在方法中添加注释以获得更好的效果understanding@stackpepe在这种情况下,我认为我的原始代码满足您的需要。为了确保秩序良好,我还添加了一个秒
一种似乎合理的情况,即计算从外部调用阶乘的次数。您同意第一个代码为您提供所需的结果吗?不幸的是,当从我得到的main执行时,您的解决方案对我不起作用:[java.lang.Thread.getStackTraceThread.java:1589,loggerService.LoggerServiceImpl.mainLoggerServiceImpl.java:103]不幸的是,当从我得到的main执行时,您的解决方案对我不起作用:[java.lang.Thread.getStackTraceThread.java:1589,loggerService.LoggerServiceImpl.mainLoggerServiceImpl.java:103]
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);
}