用 JavaScript 的方式理解遞歸

原文地址

1. 遞歸是啥?

遞歸概念很簡單,“自己調用自己”(下面以函數為例)。

在分析遞歸之前,需要了解下 JavaScript 中“壓棧”(call stack) 概念。

2. 壓棧與出棧

是什么?可以理解是在內存中某一塊區域,這個區域比喻成一個箱子,你往箱子里放些東西,這動作就是壓棧。所以最先放下去的東西在箱子最底下,最后放下去的在箱子最上面。把東西從箱子中拿出來可以理解為出棧

所以得出結論,我們有個習慣,拿東西是從上面往下拿,最先放下去的東西在箱子的最底下,最后才能拿到。

在 JavaScript 中,調用函數時,都會發生壓棧行為,遇到含 return 關鍵字的句子或執行結束后,才會發生出棧(pop)。

來看個例子,這個段代碼執行順序是怎樣的?

function fn1() {return 'this is fn1'
}function fn2() {fn3()return 'this is fn2'
}function fn3() {let arr = ['apple', 'banana', 'orange']return arr.length
}function fn() {fn1()fn2()console.log('All fn are done')
}fn()
復制代碼

上面發生了一系列壓棧出棧的行為:

  1. 首先,一開始棧(箱子)是空的
  2. 函數 fn 執行,fn 先壓棧,放在棧(箱子)最底下
  3. 在函數 fn 內部,先執行函數 fn1fn1 壓棧在 fn 上面
  4. 函數 fn1 執行,遇到 return 關鍵字,返回 this is fn1fn1 出棧,箱子里現在只剩下 fn
  5. 回到 fn 內部,fn1 執行完后,函數 fn2 開始執行,fn2 壓棧,但是在 fn2 內部,遇到 fn3,開始執行 fn3,所以 fn3 壓棧
  6. 此時棧中從下往上順序為:fn3 <= fn2 <= fnfn 在最底下
  7. 以此類推,函數 fn3 內部遇到 return 關鍵字的句子,fn3 執行完結束后出棧,回到函數 fn2 中 ,fn2 也是遇到 return 關鍵字,繼續出棧。
  8. 現在棧中只有 fn 了,回到函數 fn 中,執行 console.log('All fn are done') 語句后,fn 出棧。
  9. 現在棧中又為空了。

上面步驟容易把人繞暈,下面是流程圖:

再看下在 chrome 瀏覽器環境下執行:

3. 遞歸

先看下簡單的 JavaScript 遞歸

function sumRange(num) {if (num === 1) return 1;return num + sumRange(num - 1)
}sumRange(3) // 6
復制代碼

上面代碼執行順序:

  1. 函數 sumRange(3) 執行,sumRange(3) 壓棧,遇到 return 關鍵字,但這里還馬上不能出棧,因為調用了 sumRange(num - 1)sumRange(2)
  2. 所以,sumRange(2) 壓棧,以此類推,sumRange(1) 壓棧,
  3. 最后,sumRange(1) 出棧返回 1,sumRange(2) 出棧,返回 2,sumRange(3) 出棧
  4. 所以 3 + 2 + 1 結果為 6

看流程圖

所以,遞歸也是個壓棧出棧的過程。

遞歸可以用非遞歸表示,下面是上面遞歸例子等價執行

// for 循環
function multiple(num) {let total = 1;for (let i = num; i > 1; i--) {total *= i}return total
}
multiple(3)
復制代碼

4. 遞歸注意點

如果上面例子修改一下,如下:

function multiple(num) {if (num === 1) console.log(1)return num * multiple(num - 1)
}multiple(3) // Error: Maximum call stack size exceeded
復制代碼

上面代碼第一行沒有 return 關鍵字句子,因為遞歸沒有終止條件,所以會一直壓棧,造成內存泄漏。

遞歸容易出錯點

  1. 沒有設置終止點
  2. 除了遞歸,其他部分的代碼
  3. 什么時候遞歸合適

好了,以上就是 JavaScript 方式遞歸的概念。

下面是練習題。

6. 練習題目

  1. 寫一個函數,接受一串字符串,返回一個字符串,這個字符串是將原來字符串倒過來。
  2. 寫一個函數,接受一串字符串,同時從前后開始拿一位字符對比,如果兩個相等,返回 true,如果不等,返回 false
  3. 編寫一個函數,接受一個數組,返回扁平化新數組。
  4. 編寫一個函數,接受一個對象,這個對象值是偶數,則讓它們相加,返回這個總值。
  5. 編寫一個函數,接受一個對象,返回一個數組,這個數組包括對象里所有的值是字符串

7. 參考答案

參考1

function reverse(str) {if(str.length <= 1) return str; return reverse(str.slice(1)) + str[0];
}reverse('abc')
復制代碼

參考2

function isPalindrome(str){ if(str.length === 1) return true;if(str.length === 2) return str[0] === str[1]; if(str[0] === str.slice(-1)) return isPalindrome(str.slice(1,-1)) return false; 
}var str = 'abba'
isPalindrome(str)
復制代碼

參考3

function flatten (oldArr) {var newArr = [] for(var i = 0; i < oldArr.length; i++){ if(Array.isArray(oldArr[i])){ newArr = newArr.concat(flatten(oldArr[i])) } else { newArr.push(oldArr[i])}}return newArr;
}flatten([1,[2,[3,4]],5])
復制代碼

參考4

function nestedEvenSum(obj, sum=0) {for (var key in obj) { if (typeof obj[key] === 'object'){ sum += nestedEvenSum(obj[key]); } else if (typeof obj[key] === 'number' && obj[key] % 2 === 0){ sum += obj[key]; }} return sum;
}nestedEvenSum({c: 4,d: {a: 2, b:3}})
復制代碼

參考5

function collectStrings(obj) {let newArr = []for (let key in obj) {if (typeof obj[key] === 'string') {newArr.push(obj[key])} else if(typeof obj[key] === 'object' && !Array.isArray(obj[key])) {newArr = newArr.concat(collectStrings(obj[key]))}}return newArr
}var obj = {a: '1',b: {c: 2,d: 'dd'}}collectStrings(obj)
復制代碼

5. 總結

遞歸精髓是,往往要先想好常規部分是怎樣的,在考慮遞歸部分,下面是 JavaScript 遞歸常用到的方法

  • 數組:slice, concat
  • 字符串: slice, substr, substring
  • 對象:Object.assign

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389420.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389420.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389420.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PyTorch官方教程中文版:Pytorch之圖像篇

微調基于 torchvision 0.3的目標檢測模型 """ 為數據集編寫類 """ import os import numpy as np import torch from PIL import Imageclass PennFudanDataset(object):def __init__(self, root, transforms):self.root rootself.transforms …

大數據數據科學家常用面試題_進行數據科學工作面試

大數據數據科學家常用面試題During my time as a Data Scientist, I had the chance to interview my fair share of candidates for data-related roles. While doing this, I started noticing a pattern: some kinds of (simple) mistakes were overwhelmingly frequent amo…

scrapy模擬模擬點擊_模擬大流行

scrapy模擬模擬點擊復雜系統 (Complex Systems) In our daily life, we encounter many complex systems where individuals are interacting with each other such as the stock market or rush hour traffic. Finding appropriate models for these complex systems may give…

公司想申請網易企業電子郵箱,怎么樣?

不論公司屬于哪個行業&#xff0c;選擇企業郵箱&#xff0c;交互界面友好度、穩定性、安全性都是選擇郵箱所必須考慮的因素。網易企業郵箱郵箱方面已有21年的運營經驗&#xff0c;是國內資歷最高的電子郵箱&#xff0c;在各個方面都非常成熟完善。 從交互界面友好度來看&#x…

莫煩Matplotlib可視化第二章基本使用代碼學習

基本用法 import matplotlib.pyplot as plt import numpy as np""" 2.1基本用法 """ # x np.linspace(-1,1,50) #[-1,1]50個點 # #y 2*x 1 # # y x**2 # plt.plot(x,y) #注意&#xff1a;x,y順序不能反 # plt.show()"""…

vue.js python_使用Python和Vue.js自動化報告過程

vue.js pythonIf your organization does not have a data visualization solution like Tableau or PowerBI nor means to host a server to deploy open source solutions like Dash then you are probably stuck doing reports with Excel or exporting your notebooks.如果…

plsql中導入csvs_在命令行中使用sql分析csvs

plsql中導入csvsIf you are familiar with coding in SQL, there is a strong chance you do it in PgAdmin, MySQL, BigQuery, SQL Server, etc. But there are times you just want to use your SQL skills for quick analysis on a small/medium sized dataset.如果您熟悉SQ…

第十八篇 Linux環境下常用軟件安裝和使用指南

提醒&#xff1a;如果之后要安裝virtualenvwrapper的話&#xff0c;可以直接跳到安裝virtualenvwrapper的方法&#xff0c;而不需要先安裝好virtualenv安裝virtualenv和生成虛擬環境安裝virtualenv&#xff1a;yum -y install python-virtualenv生成虛擬環境&#xff1a;先切換…

莫煩Matplotlib可視化第三章畫圖種類代碼學習

3.1散點圖 import matplotlib.pyplot as plt import numpy as npn 1024 X np.random.normal(0,1,n) Y np.random.normal(0,1,n) T np.arctan2(Y,X) #用于計算顏色plt.scatter(X,Y,s75,cT,alpha0.5)#alpha是透明度 #plt.scatter(np.arange(5),np.arange(5)) #一條線的散點…

計算機科學必讀書籍_5篇關于數據科學家的產品分類必讀文章

計算機科學必讀書籍Product categorization/product classification is the organization of products into their respective departments or categories. As well, a large part of the process is the design of the product taxonomy as a whole.產品分類/產品分類是將產品…

es6解決回調地獄問題

本文摘抄自阮一峰老師的 http://es6.ruanyifeng.com/#docs/generator-async 異步 所謂"異步"&#xff0c;簡單說就是一個任務不是連續完成的&#xff0c;可以理解成該任務被人為分成兩段&#xff0c;先執行第一段&#xff0c;然后轉而執行其他任務&#xff0c;等做好…

交替最小二乘矩陣分解_使用交替最小二乘矩陣分解與pyspark建立推薦系統

交替最小二乘矩陣分解pyspark上的動手推薦系統 (Hands-on recommender system on pyspark) Recommender System is an information filtering tool that seeks to predict which product a user will like, and based on that, recommends a few products to the users. For ex…

莫煩Matplotlib可視化第四章多圖合并顯示代碼學習

4.1Subplot多合一顯示 import matplotlib.pyplot as plt import numpy as npplt.figure() """ 每個圖占一個位置 """ # plt.subplot(2,2,1) #將畫板分成兩行兩列&#xff0c;選取第一個位置,可以去掉逗號 # plt.plot([0,1],[0,1]) # # plt.su…

python 網頁編程_通過Python編程檢索網頁

python 網頁編程The internet and the World Wide Web (WWW), is probably the most prominent source of information today. Most of that information is retrievable through HTTP. HTTP was invented originally to share pages of hypertext (hence the name Hypertext T…

Python+Selenium自動化篇-5-獲取頁面信息

1.獲取頁面title title&#xff1a;獲取當前頁面的標題顯示的字段from selenium import webdriver import time browser webdriver.Chrome() browser.get(https://www.baidu.com) #打印網頁標題 print(browser.title) #輸出內容&#xff1a;百度一下&#xff0c;你就知道 2.…

火種 ctf_分析我的火種數據

火種 ctfOriginally published at https://www.linkedin.com on March 27, 2020 (data up to date as of March 20, 2020).最初于 2020年3月27日 在 https://www.linkedin.com 上 發布 (數據截至2020年3月20日)。 Day 3 of social distancing.社會疏離的第三天。 As I sit on…

莫煩Matplotlib可視化第五章動畫代碼學習

5.1 Animation 動畫 import numpy as np import matplotlib.pyplot as plt from matplotlib import animationfig,ax plt.subplots()x np.arange(0,2*np.pi,0.01) line, ax.plot(x,np.sin(x))def animate(i):line.set_ydata(np.sin(xi/10))return line,def init():line.set…

data studio_面向營銷人員的Data Studio —報表指南

data studioIn this guide, we describe both the theoretical and practical sides of reporting with Google Data Studio. You can use this guide as a comprehensive cheat sheet in your everyday marketing.在本指南中&#xff0c;我們描述了使用Google Data Studio進行…

人流量統計系統介紹_統計介紹

人流量統計系統介紹Its very important to know about statistics . May you be a from a finance background, may you be data scientist or a data analyst, life is all about mathematics. As per the wiki definition “Statistics is the discipline that concerns the …

pyhive 連接 Hive 時錯誤

一、User: xx is not allowed to impersonate xxx 解決辦法&#xff1a;修改 core-site.xml 文件&#xff0c;加入下面的內容后重啟 hadoop。 <property><name>hadoop.proxyuser.xx.hosts</name><value>*</value> </property><property…