使用遞迴函式重寫程式設計練習8 程式設計風格的練習,遞迴

2021-10-07 23:25:33 字數 2918 閱讀 7693

使用遞迴函式重寫程式設計練習8

本週的帖子將回到基礎知識,因為限制是使用遞迴 :

電腦科學中的遞迴是一種解決問題的方法,其中解決方案取決於對同一問題的較小例項(而不是迭代)的解決方案。 該方法可以應用於多種型別的問題,而遞迴是電腦科學的中心思想之一。

—維基百科

遞迴((computer_science)

這是4在程式設計風格焦點series.other職位練習日交包括:

以程式設計風格介紹練習

以程式設計風格進行練習,將內容堆疊起來

程式設計風格的練習,kwisatz haderach風格

程式設計風格的練習,遞迴 (本文)

具有高階功能的程式設計風格的練習

以程式設計風格進行練習

以程式設計風格進行練習,回到物件導向的程式設計

程式設計風格的練習:地圖也是物件

程式設計風格的練習:事件驅動的程式設計

程式設計風格的練習和事件匯流排

反思程式設計風格的練習

面向方面的程式設計風格的練習

程式設計風格的練習:fp&i / o

關聯式資料庫風格的練習

程式設計風格的練習:電子**

併發程式設計風格的練習

使用hazelcast以程式設計風格進行練習

mapreduce風格的練習

程式設計風格的練習總結

我已經在將函式式程式設計的方法應用於dijkstra演算法的上下文中寫過關於遞迴的文章。 讓我們詳細了解其實現。 遞迴函式應提供兩個分支:

停止分支返回最終結果

乙個使用不同引數呼叫函式本身的分支

這是階乘函式的簡單實現:

fun

fact(n

:int

):int

return

result

}fact(5

)

在傳統的命令式程式設計中,函式使用區域性變數來累積臨時計算。 在遞迴函式中,這些變數被函式引數替換。

private

funrecursefact

(acc

:int,n

:int

):int=if

(n==1

)acc

(1)else

recursefact

(acc*n

,n-1

)(2)fun

fact(n

:int)=

recursefact(1

,n)(3)fact(5

)

停止分支

自呼分支

與以前的功能簽名相同

請注意,acc引數與命令示例中的result區域性變數具有相同的作用。

以下是練習中的功能。 它採用與階乘示例完全相同的原理:

fun

words

(rest

:list

<

string

>,

stopwords

:list

<

string

>,

words

:list

<

string

>):

list

<

string

>

}

儘管遞迴**比命令**更為簡潔,但是它卻遇到了乙個巨大的問題:函式呼叫被推入執行緒的呼叫堆疊中。 超出呼叫堆疊的大小時,將引發臭名昭著的stackoverflowerror

儘管可以在啟動時設定堆疊大小,但是堆疊大小是有限的。

用於管理堆疊大小的命令列選項-xss標準jvm hotspot選項-xx:threadstacksize專有選項如有更改,恕不另行通知
為了解決這個問題,kotlin(和scala)提供了乙個編譯器技巧:儘管源**是遞迴的,但是編譯後的位元組碼是通過標準迴圈實現的。 有兩個要求:

遞迴函式呼叫必須是最後乙個。

這稱為拖尾遞迴 。

修飾符tailrec必須新增到功能簽名中

上面的words()函式是尾遞迴的,因此新增tailrec關鍵字非常容易。 可以相應地對其進行更新,以使其永遠不會溢位。

相反,以下函式不是尾遞迴的,因為有兩個使用遞迴的呼叫。 因此, 位元組碼不能被優化。

fun

<

t>

quicksort

(list

:list

<

pair

int>>):

list

<

pair

int>>=if

(list

.size

<=1)

list

else

list

.random

().let

valabove

=filter

(list

,listof

())quicksort

(below

-pivot)+

pivot

+quicksort

(above

)}

通常,遞迴是一開始很難破解的螺母。 但是,遷移**以使用遞迴很簡單:只需將區域性變數移動到累加器引數即可。 最難的部分是使遞迴函式尾遞迴以避免堆疊溢位。 有些功能允許,有些則不允許。

這篇文章的完整源**可以在github上找到。

翻譯自:

使用遞迴函式重寫程式設計練習8

第三週函式的遞迴 程式設計作業 遞迴程式設計練習

注意 總時間限制 1000ms 記憶體限制 65536kb 輸入乙個句子 一行 將句子中的每乙個單詞翻轉後輸出。只有一行,為乙個字串,不超過500個字元。單詞之間以空格隔開。所謂單詞指的是所有不包含空格的連續的字元。這道題請用cin.getline輸入一行後再逐個單詞遞迴處理。翻轉每乙個單詞後的字串...

程式設計風格的練習,遞迴

本週的帖子將回到基礎知識,因為限制是使用遞迴 電腦科學中的遞迴是一種解決問題的方法,其中解決方案取決於對同一問題的較小例項 而不是迭代 的解決方案。該方法可以應用於許多態別的問題,並且遞迴是電腦科學的中心思想之一。維基百科 遞迴 computer science 這是4在程式設計風格焦點series...

程式設計練習8 全排列

給定乙個數字列表,返回其所有可能的排列。給出乙個列表 1,2,3 其全排列為 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 每次固定乙個元素,將其他的元素進行全排列,例如第一次固定1,將2,3進行全排列,得到 1,2,3 和 1,3,2 第二次固定2,將2交換至第一位,得到...