首页 > 编程语言 >【笔记05】Javascript - 基本概念 - (函数递归)

【笔记05】Javascript - 基本概念 - (函数递归)

时间:2022-10-28 21:32:06浏览次数:62  
标签:function return 递归 05 Javascript fib num 阶乘 fac

先看一个试题: 求n的阶乘

通常,我们会写:

function fac(num){
var res = 1;
for(var i = 1; i <= num; i++){
res *= i;
}
return res;
}

观察阶乘可以发现两个特点:

特点一:有规律

5! = 5 * 4 * 3 * 2 * 1

发现 5 的阶乘等于 5 乘以 4 的阶乘,同理,4 的阶乘是 4 乘以 3 的阶乘。

5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
... ...

特点二:有出口

出口是已知的,就是 1 的阶乘等于 1.

1! = 1

根据这两个特点,可以把函数改一下;

function fac(num){
if(num == 1){ // 出口条件
return 1; // 出口的值已知
}
return num * fac(num -1); // 抽象出规律
}

可以再推倒一遍:

fac(5);

fac(5) ==> 5 * fac(4); // 想知道 5 的结果,就得需要先知道 4 的结果
fac(4) ==> 4 * fac(3); // 想知道 4 的结果,还得先知道 3 的结果
fac(3) ==> 3 * fac(2); // 想知道 3 的结果,得先知道 2 的结果
fac(2) ==> 2 * fac(1); // 想知道 2 的结果,得先知道 1 的结果
fac(1) ==> 1 已知 // 1 的结果已知,往上反推回去

fac(2) = 2 * 1;
fac(3) = 3 * 2;
fac(4) = 4 * 6;
fac(5) = 5 * 24; // 120

这就是用递归的方法来解决。

递归比较符合人的思维,找到规律和出口,就可以使用递归的思想来写代码。

所以,按这个思路,再把 N 的阶乘,再理一遍。

// 1. 找规律
// 2. 找出口

// 规律: n! = n * (n - 1)!

根据规律,直接写函数:

function fac(num){

return num * fac(num - 1); // 直接 return 规律公式
}

然后进行推倒,比如 3 的阶乘;

fac(3) ==> 3 * fac(2)
fac(2) ==> 2 * fac(1);
fac(1) ==> 1 * fac(0);

这时,必须要找个出口,不然函数成了无限死循环。

已知条件: 1 的阶乘是 1。

function fac(num){
if(num == 1){ // 设置一个出口
return 1; // 出口值为1
}
return num * fac(num - 1);
}

但这是没有办法求 0 的阶乘,而 0 的阶乘等于 1,所以给他补上。

function fac(num){
if(num == 1 || num == 0){
return 1;
}
return num * fac(num - 1);
}

fac(5); // 120

递归的时间复杂度比较大,所以效率低下。


根据递归的思路,再来写一个斐波那契数列的递归函数。

// 1. 找规律
// 2. 找出口

// 第N位的值等于第(n-1)和第(n-2)位的和
// 规律: fib(n) = fib(n - 1) + fib(n - 2)

function fib(n){

return fib(n - 1) + fib(n - 2); // 根据规律,直接写return
}

推倒一下:

fib(5) ==> fib(4) + fac(3);
fib(4) ==> fib(3) + fac(2);
fib(3) ==> fib(2) + fac(1);

这时,找出口。 我们已知 fib(1) 和 fib(2) 的结果是1,所以直接把出口条件写在函数里。

function fib(n){
if(n == 1 || n == 2){ // 设置出口条件
return 1; // 出口值
}
return fib(n - 1) + fib(n - 2);
}

fib(8); // 21



标签:function,return,递归,05,Javascript,fib,num,阶乘,fac
From: https://blog.51cto.com/ahuiok/5805272

相关文章

  • JavaScript--DOM
    一、DOM的概述1、文档对象模型(DOM,DocumentObjectModel)是HTML和XML文档的编程接口。DOM表示由多层节点构成的文档,通过它开发者可以添加、删除和修改页面的各个部分......
  • JavaScript--ES5和ES6(上)
    一、概述es表示ECMASCript,他是从es3,es5,es6,es5是2009.12月发布的,es6是2015.6月发布的。vue2完全支持es5的(vue3完全支持es6的),react完全支持es6二、es5的新特性1、严格模......
  • JavaScript--cookie
    一、概述cookie总是保存在客户端中(浏览器端)。cookie为了保存sessionID出现的。cookie的出现解决了http无状态的问题。二、特性cookie是不安全的cookie是可以被篡......
  • JavaScript--Date
    一、Date的概述在JavaScript中,Date类型是用来保存日期的,它能精确到1970年1月1日之前或之后的285616年。二、Date的声明使用new关键字声明要创建一个日期对象,使用new操......
  • JavaScript--_==_和_===_
    一、""和"="简单介绍1)宽松相等(looseequals)==和严格相等(strictequals)===都用来判断两个值是否“相等”,但是它们之间有一个很重要的区别,特别是在判断条件上。2)正确的解......
  • JavaScript--AJXS
    协议(基于tcp/ip)超文本传输协议(HyperTextTransferProtocol,HTTP)是用于从WWW服务器传输超文本到本地浏览器的传输协议(transport)。它可以使浏览器更加高效,使网络传输减少。......
  • JavaScript--BOM
    一、BOM的概述虽然ECMAScript把浏览器对象模型(BOM,BrowserObjectModel)描述为JavaScript的核心,但实际上BOM是使用JavaScript开发Web应用程序的核心。BOM提供了......
  • JavaScript--初识
    一、JavaScript的了解1995年,网景公司与Sun公司结为开发联盟,共同完成LiveScript的开发。后网景把LiveScript改名为JavaScript。二、JavaScript的概述JavaScript是一个轻......
  • JavaScript--Math
    一、概述ECMAScript提供了Math对象作为保存数学公式、信息和计算的地方。Math对象提供了一些辅助计算的属性和方法。注意:Math对象上提供的计算要比直接在JavaScrip......
  • JavaScript--JSONP和Axios
    JSONP概述:JSONP(JSONwithpadding)是一种跨域解决方案,它主要是利用了script标签不受跨域影响的特性来完成对应的请求操作。实际上是一个get请求。JSONP格式包含两个部分:......