day 04 函數《有趣的遞歸函數》

来源:https://www.cnblogs.com/jxooooolxe/archive/2022/07/28/16529890.html
-Advertisement-
Play Games

函數函數概述函數 實際就是多行代碼的抽取(多行代碼會構成特定的功能)(方法)函數的優點減少冗餘代碼(重覆的代碼放在函數裡面 在需要的時候調用)函數封裝(特定的一些代碼使用函數來包起來),提高了代碼的可維護性及可閱讀性函數的分類1.系統函數 window裡面的所有函數都屬於系統函數 (console. ...


函數
函數概述
函數 實際就是多行代碼的抽取(多行代碼會構成特定的功能)(方法)
函數的優點
減少冗餘代碼(重覆的代碼放在函數裡面 在需要的時候調用)函數封裝(特定的一些代碼使用函數來包
起來),
提高了代碼的可維護性及可閱讀性
函數的分類
1.系統函數 window裡面的所有函數都屬於系統函數 (console.log() alert() prompt()...)
2.內置函數 所有的內置對象裡面的函數 都叫內置函數 (Math.pow())
3.自定義函數( 自己定義的函數)
內置函數和系統函數我們更關註於他的使用 自定義函數(定義以及使用)

1.使用function關鍵詞 定義匿名函數(沒有名字的函數)(個人感覺用途不是很廣,因為,他沒有復用價值,只能一次一次的用)

function(形參(可以省略的 可以有多個)){
函數體(代碼)
}
//直接調用 讓別人(事件)去調用(自動調用)
(function(){
console.log('匿名函數')
})()

2.使用function關鍵詞 定義具名函數 (有名字的函數)(聲明試,有名字,可以隨便調用)

 

function 函數名(形參,形參...){
函數體(代碼)
}
//聲明 具名函數(第一種)
function sayHello(){
console.log('hello')
}
sayHello()
//傳遞參數
function sayHello1(name,age){ //形參是形容的參數
console.log('hello'+name+age)
}
sayHello1('李四') //傳進的是實參 根據你要的參數個數來傳遞對應的參數個數
//調用
// sayHi() //報錯
// console.log(sayHi); undefined
//具名函數的變種聲明 (第二種)
var sayHi = function(){
console.log('hi')
}
sayHi()

3.使用new Function方式(賦值法)

 

var 函數名 = new Function('形參,形參1','函數體')
//定義
var sayBye = new Function('console.log("bye bye!!")')
//調用
sayBye()
//傳參
var sayBye = new Function('username','console.log("bye bye!!"+username)')
//調用
sayBye('李四')

 

在程式執行之前有個預編譯過程

預編譯

 

1.他會聲明對應的function和var關鍵詞修飾的變數(開闢記憶體的操作)
2.對應的function的記憶體空間開闢以後他會將對應的代碼塊放到其中 等待調用
3.var 修飾的關鍵詞 只會開闢一個空間 並不會進行賦值(預設給他的一個undefined的值)

return 

return 返回對應的數據的 他是在函數內容進行數據返回的(當你調用了return操作後 後面的內容將不
再執行)即:只要有return他就會跳出來,不會在執行後面的相關程式了!

function sum(a,b){
return a+b
console.log('不會執行的代碼')
}
console.log(sum(1,2))//返回的對應的1+2的結果

如果沒有return關鍵詞 返回的一個undefined的值,因為你沒有返回值,所以沒有返回值,所以sayHi裡面啥也沒有所以會輸出undefined

function sayHi(){
console.log('hi')
}
console.log(sayHi()) //undefined

函數執行過程
1.把對應的開闢的function記憶體裡面的代碼塊丟給方法棧(執行棧)去執行
2.執行棧就會自動取執行對應的方法 執行完返回對應的結果
3.當前結果返回完畢以後 對應的執行棧裡面的記憶體空間要進行回收(GC)將這個記憶體空間銷毀

函數作用域
作用域
當前一個變數的作用範圍 分為局部作用域(在一個函數內聲明的 或者是在一段代碼塊內聲明的 他的作
用範圍就是當前的代碼塊)和全局作用域(在對應的全局聲明的 他的作用範圍就是全局的)

作用域鏈(個人理解往上面找,找爸爸借錢,不找兒子借錢)

 

 

 

var a = 20
function fn(){
console.log(a);//undefined 沒有var關鍵詞就20
var a = 10
if(10>9){
console.log(a);//undefined 沒有var關鍵詞就10
var a = 30
if(5>4){
console.log(a);//undefined 沒有var關鍵詞就30
var a = 40
if(a>10){
console.log(a);//40
}
}
}
}
fn()

 

 

 

 

 

函數的arguments(參數數組 參數的集合)
arguments是一個偽數組(有部分的數組特性)(可以通過length屬性對應的長度 [] 下標來訪問裡面的
元素)(個人理解:即有數組的性質但是,不是數組)

function sum(){ //不清楚參數個數(無參)
// arguments 可以接收裡面所有的參數
//獲取裡面傳遞的所有的參數 arguments 長度length
//下標索引是從0開始的
var result = 0
//遍歷對應的arguments裡面的所有的參數
for(var i=0;i<arguments.length;i++){
result += arguments[i] //取出裡面的參數進行求和
}
return result
}

所有的函數都具備arguments (對象)
訪問
1.length屬性訪問長度
2.[] 加下標(從0開始)訪問裡面的元素
函數的嵌套
函數的嵌套: 函數內部可以再包含其他函數;
函數之間允許相互調用,也允許向外調用, 但是不可以調用同級函數的嵌套函數;

(個人理解:能給自己兒子借錢,可以給朋友借錢,但是不能給朋友的兒子借錢)

 

function fn1(){
console.log('函數1');
function fn2(){
console.log('函數2');
// fn1() 沒有結束就是死迴圈
}
function fn3(){
console.log('函數3');
//調用函數2
fn2()
}
fn2()
fn3()
}
fn1() //函數1 函數2 函數3 函數2

 

註意事項
函數的抽取 (抽取冗餘的代碼)
1.參數 (可變的內容)
2.返回值 (我們想從這個函數得到什麼)

Dom的簡單操作
1.獲取對應的標簽 (通過id獲取)

document.getElementById('id的屬性值')

2.input框的值獲取 value屬性

document.getElementById('input框的id').value //得到input框內的值

3.點擊事件 onclick

element.onclick = function(){
//相關操作
}

示例(以事件做為驅動)

//通過輸入框輸入數值判斷對應的奇偶並列印
<input id="number" type="text">
<button id="btn">判斷奇偶</button>
<script>
function handlerClick(){
//拿到input框裡面的內容 獲取到input框
var inputValue = document.getElementById('number').value //string類型
// console.log(typeof inputValue); 如果是+法操作必須要先轉類型
//判斷奇偶的操作
if(inputValue%2==0){
console.log('當前為偶數');
}else{
console.log('當前為奇數');
}
}
//首先需要點擊按鈕 獲取按鍵 加點擊事件
//事件觸發自動調用對應的函數 (事件驅動)
document.getElementById('btn').onclick = handlerClick
</script>

遞歸演算法*
遞歸可以完成所有迴圈做的事情 (但是遞歸的效率較低)
遞歸三要素
1.找規律
2.找臨界值(沒有規律的值)return
3.自己調自己(在函數內部調用自己的函數)
2 4 6 8 10 第100的值是什麼

 

function fn(n){ //一般情況都會有參數 n表示為位數
if(n==1){//沒規律的(一般在前面或者後面)
return 2 //返回具體的值
}else{ //有規律的 返回對應的規律的公式
return fn(n-1)+2
}
}
console.log(fn(100))

 

示例

 

// 1 3 6 10 15 21 第100位 前一位+對應的位數 = 這個一位的值
function fn1(n){
if(n==1){
return 1
}else{
return fn1(n-1)+n
}
}
console.log(fn1(6));
// 1 2 3 5 8 13 21 第100位值(遞歸的效率極低 一般不使用遞歸 不推薦 (文件的遍歷 菜單遍歷 深
拷貝))
function fn2(n){
if(n==1){
return 1
}else if(n==2){
return 2
}else{
return fn2(n-2)+fn2(n-1)
}
}
console.log(fn2(7));

 

bfs 廣度優先搜索 dfs 深度優先搜索(遞歸思想)

作業::遞歸

  //第8題  兔子繁殖問題,設有一隻新生兔子,從第四個月開始他們每個月, 月初都生一隻兔子, 新生的兔子從第四個月月初開始又每個月生一隻兔子按此規律,並假定兔子沒有死亡, n(n<=20)個月月末共有多少只兔子?

    function fn6(n) {
        if (n <= 3) {
            return 1
        } else {
            return fn6(n-1)+fn6(n-3)
        }
    }
    console.log(fn6(11));
    //3天就可以生一個兔子兔子後面可以一天生一個
    function fn7(n){
        if(n<=2){
            return 1
        }else{
            return fn7(n-1)+fn7(n-2)
        }
    }
    console.log(fn7(10));

兔子繁殖問題,設有一隻新生兔子,從第四個月開始他們每個月, 月初都生一隻兔子, 新生的兔子從第四個月月初開始又每個月生一隻兔子按此規律,並假定兔子沒有死亡, n(n<=20)個月月末共有多少只兔子?(題目解釋,有過程)

   function fn6(n) {
        if (n <= 3) {
            return 1
        } else {
            return fn6(n-1)+fn6(n-3)
        }
    }
    console.log(fn6(11));
    //第一列表示月數   第一行表示當前月份中各個月份的兔子的數量
    //  1  2  3  4
    //1 1  0  0  0  1
    //2 0  1  0  0  1
    //3 0  0  1  0  1
    //4 1  0  0  1  2 //註意這個是第一個兔子生孩子了,所以會有一個還在一月份的兔子
    //5 1  1  0  1  3
    //6 1  1  1  1  4
    //7 2  1  1  2  6//第二個兔子也可以生孩子了
    //8 3  2  1  3  9
    //9 4  3  2  4  13
   //10 6  4  3  6  19    找規律的f(m) = f(n-1) + f(n-3) 然後掏遞歸公式咯,一下就出來了
   

今天的總結完畢咯!!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用flink的時候難免和redis打交道,相信大家都使用過flink-connector-redis來處理,但是當我想要使用RedisSink寫入集群時,發現居然不支持使用密碼,於是有了這篇筆記。 ...
  • 19 | 為什麼我只查一行的語句,也執行這麼慢? 有些情況下,“查一行”,也會執行得特別慢。 需要說明的是,如果 MySQL 資料庫本身就有很大的壓力,導致資料庫伺服器 CPU 占用率很高或 ioutil(IO 利用率)很高,這種情況下所有語句的執行都有可能變慢,不屬於本章討論範圍。 為了便於描述, ...
  • 18 | 為什麼這些SQL語句邏輯相同,性能卻差異巨大? 在 MySQL 中,有很多看上去邏輯相同,但性能卻差異巨大的 SQL 語句。對這些語句使用不當的話,就會不經意間導致整個資料庫的壓力變大。 三個案例 案例一:條件欄位函數操作 假設你現在維護了一個交易系統,其中交易記錄表 tradelog 包 ...
  • 步驟一:設置sql server資料庫 1.以新建一個新用戶名test作為遠程連接登錄名。在本地登錄sql server資料庫,安全性->右鍵用戶名 2.點擊根目錄右鍵,選擇屬性 選擇安全性 選擇連接,勾上允許遠程連接到此伺服器,點擊確定 3.設置伺服器的方面選項 4.設置sql server 配置 ...
  • 上篇文章講了MySQL架構體系,瞭解到MySQL Server端的優化器可以生成Explain執行計劃,而執行計劃可以幫助我們分析SQL語句性能瓶頸,優化SQL查詢邏輯,今天就一塊學習Explain執行計劃的具體用法。 ...
  • 2008年,“大數據”一詞在《大數據時代》中被首次提出,距今已有整整14個年頭。在這14年中,許多人親眼見證了數據的力量,以及目睹它如何改變世界。大部分企業的決策者都明白了一個道理:數據才是企業中最有價值的商品,它可以被人為選擇成就還是破壞業務。 然而,自流行詞“大數據”出現的14年後,如何獲得更高 ...
  • 最近一鍵“露齒笑”席卷全網,無論是短視頻用戶還是社交App用戶都在使用這項黑科技。當三兩好友聚會拍集體照留念時,為了處理個別人的表情“瑕疵”,讓大家都儘量保持微笑,總要進行表情微調,但如果需要進行複雜的換頭換臉等P圖操作,對用戶來說門檻太高。有些用戶“鏡頭恐懼”,拍照時不會微笑、表情尷尬;有些用戶對 ...
  • 這幾天正式開始微信小程式的修煉了,就目前而言來看簡直就是vue和react的結合體,所以在學小程式前,先把框架熟悉還是挺有用的。 一.簡介 1.1與普通網頁區別 二.第一個小程式 需要註冊小程式開發賬號,==最主要是獲得AppId== 然後就需要安裝 ==微信開發者工具== 2.1設置外觀和代理 2 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...