You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何追踪JavaScript递归斐波那契函数并统计递归调用次数

追踪递归斐波那契函数的调用次数

嘿,我完全理解你想追踪这个递归斐波那契函数调用次数的需求——虽然递归求斐波那契确实效率不高,但用来学习递归调用流程还是挺合适的。你提到的15次调用应该是输入num=5时的情况对吧?咱们来一步步实现这个计数器,有几种不同的方案可以选:

方案1:全局计数器(简单直观)

这是最容易上手的方式,定义一个全局变量统计调用次数,每次进入fibonacci函数就把计数器加1:

// 初始化全局计数器
let callCount = 0;

function fibonacci(num) {
  callCount++; // 每次调用函数就计数+1
  // 可选:打印每次调用的参数,清晰看到执行步骤
  console.log(`正在执行 fibonacci(${num})`);
  
  if (num < 2) {
    return num;
  }
  return fibonacci(num - 1) + fibonacci(num - 2);
}

// 测试求fib(5),预期总调用次数15次
fibonacci(5);
console.log(`总调用次数:${callCount}`);

注意点:

  • 如果要多次测试,记得每次调用前重置callCount = 0,不然计数会累加
  • 全局变量可能会被其他代码意外修改,适合简单测试场景

方案2:闭包封装计数器(更优雅,无全局污染)

如果不想用全局变量,可以用闭包把计数器封装起来,既保留计数功能,又不会污染全局作用域:

function createTrackedFibonacci() {
  // 闭包内的计数器,外部无法直接修改
  let callCount = 0;

  function fibonacci(num) {
    callCount++;
    console.log(`调用 fibonacci(${num})`);
    
    if (num < 2) {
      return num;
    }
    return fibonacci(num - 1) + fibonacci(num - 2);
  }

  // 返回操作接口,方便获取计数和重置
  return {
    fibonacci,
    getCallCount: () => callCount,
    resetCount: () => { callCount = 0; }
  };
}

// 使用方式
const trackedFib = createTrackedFibonacci();
trackedFib.fibonacci(5);
console.log(`总调用次数:${trackedFib.getCallCount()}`); // 输出15

// 重置后可以再次测试
trackedFib.resetCount();
trackedFib.fibonacci(3);
console.log(`总调用次数:${trackedFib.getCallCount()}`); // 输出5

这个方案更健壮,适合需要多次测试或者在复杂项目中使用的场景。

方案3:参数传递计数器(无状态调用)

如果你不想依赖外部变量,可以把计数器作为可选参数传递给递归函数,每次递归时更新计数:

function fibonacci(num, callCount = 0) {
  callCount++;
  console.log(`调用 fibonacci(${num}),当前累计调用:${callCount}`);
  
  if (num < 2) {
    // 返回结果和当前计数
    return { result: num, count: callCount };
  }
  // 递归调用左分支,获取左分支的结果和累计计数
  const leftBranch = fibonacci(num - 1, callCount);
  // 把左分支的计数传递给右分支,继续累计
  const rightBranch = fibonacci(num - 2, leftBranch.count);
  
  // 返回最终结果和总计数
  return {
    result: leftBranch.result + rightBranch.result,
    count: rightBranch.count
  };
}

// 测试
const { result, count } = fibonacci(5);
console.log(`fib(5)的结果:${result}`);
console.log(`总调用次数:${count}`); // 输出15

这个方案的好处是每次调用都是独立的,不需要额外重置操作,但需要修改函数的返回值来同时携带结果和计数。

为什么你之前可能没成功?

大概率是计数器的位置不对——比如你可能把计数逻辑放在了if(num<2)的判断之后,这样base case(num=0或num=1)的调用就没被统计进去,导致计数比实际少。一定要把callCount++放在函数的最开头,确保每一次函数调用都被计数。

内容的提问来源于stack exchange,提问作者Joji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:40:18