在递归中使用基本情况多次获得相同的值

Posted

技术标签:

【中文标题】在递归中使用基本情况多次获得相同的值【英文标题】:getting the same value multiple times with base case in recursion 【发布时间】:2021-10-03 10:18:51 【问题描述】:

//aim -> Given a number n, return the number of steps required to reach 1.
//ex -> when n=12, we get 9 steps


// export 
const steps = (num) => 
  //function to check if the number is positive integer
  isValid=n=>n>0;
  

  if(isValid(num))
    //base case -> the number becomes 1
    if(num===1)
      return 1;
    
    //if the number is not equal to 1
    else
      //if the number is even do n/2 and return it again
      if(num%2===0)
        return steps(num/2);
      
      else

        return steps(3*num+1);
      
    
  

;
console.log( steps(12) )
/**
 * lets do with recursion:
 * take an input num
 * if the number is 1, return 1 (base case)
 * if the number is not 1 but even, do cal=num/2  and return step(cal) back to the function
 * if the number is not 1 bu odd, do cal = 3*num+1
 */

当我控制台记录 isEven 时,我得到 1-> 3 次,当我执行 isOdd console.log 时,我得到了很多次。

这里有什么问题?以后我该如何预防?谢谢!

【问题讨论】:

这是一个让您熟悉调试器使用的好机会。使用浏览器的调试工具,您可以放置​​一个断点来暂停代码的执行,并逐行执行该执行,单步执行调用的函数等,观察变量值的变化。当你这样做时,哪个操作首先产生了意想不到的结果?使用了哪些值?结果如何?预期的结果是什么?为什么? "当我控制台记录 isEven 时,我得到 1-> 3 次,当我执行 isOdd console.log 时,我得到了很多次。" @987654321 @。我看不出你认为问题出在哪里。 来自here 从n = 12开始,得到序列12、6、3、10、5、16、8、4、2、1 - 所以该序列中有三个奇数。也许您在 isOdd console.log 中看到了这一点,而代码中没有显示。 【参考方案1】:

自己看:您的案例只考虑计算值,不计算步数

const cl = (n, op ,v )=> console.log(`$n -->$op =  $v`)

const steps = num =>
  
  if(num > 0)
    
    if (num===1)  cl(1,'-',1);  return 1 
    else
      
      if (num%2===0)  cl(num, 'n/2',   num/2  );  return steps(num/2)   
      else            cl(num, '3*n+1', 3*num+1);  return steps(3*num+1) 
      
    
  else return 'invalid num'
  
  
console.log( 'steps(12) =', steps(12) )
.as-console-wrapper max-height: 100%!important;top:0 

一个“正确”的解决方案:

const stepsCount = (num, step=0) =>
  
  step++
  if(num > 0)
    
    if (num===1)  return step 
    else
      
      if (num%2===0) return stepsCount(num/2,   step)   
      else           return stepsCount(3*num+1, step) 
      
    
  else return 'invalid num'
  
 
console.log( 'stepsCount(12) =', stepsCount(12) )

【讨论】:

我明白了。所以它所缺少的只是一个计步器?我还能做些什么来提高我的递归理解并尝试减轻此类错误?谢谢! @ShahidAlam 我不能说,有时心理障碍会阻止我们在技术点上前进(情绪 pb)。最好的方法是练习、练习……【参考方案2】:

您的日志结果是被调用函数的最后一次迭代的输出。 如果通过此函数跟踪num,您将获得所有迭代

const steps = (num) => 
 //function to check if the number is positive integer
 isValid=n=>n>0;
 console.log("e",num);

 if(isValid(num))
 //base case -> the number becomes 1
 if(num===1)
  return 1;
 
 //if the number is not equal to 1
 else
  //if the number is even do n/2 and return it again
  if(num%2===0)
    return steps(num/2);
  
  else

    return steps(3*num+1);
  
 


;
console.log( steps(12) );

【讨论】:

我能做些什么来提高我对递归的理解?谢谢! 想象一个泡泡,你在泡泡之外,看不到泡泡里面发生了什么。你的职能是一个有一系列事情要做的人,他在那个泡泡里。如果你打电话给那个人并告诉他“你列出并告诉我你什么时候完成”,那个人会做他的清单,只有当它完成时他才会告诉你。即使其中一项任务是“给自己注意:再做一遍”,由于工作没有完成,他不能告诉你。所以你必须在他的列表中输入“这里:告诉我的老板我的工作状态”

以上是关于在递归中使用基本情况多次获得相同的值的主要内容,如果未能解决你的问题,请参考以下文章

在循环中更新对象值,使用 Vue 在所有项目上获得相同的值

如何使用 Promise Kit 调用递归函数?

如何在表单中多次使用相同的字段?

如何在 PL/SQL 中使用循环多次运行相同的查询?

互斥锁递归锁读写锁和自旋锁区别

我的指针导致“多次使用相同类型的限定符”警告?