亚洲区国产区激情区无码区,国产成人mv视频在线观看,国产A毛片AAAAAA,亚洲精品国产首次亮相在线

Erlang 遞歸

遞歸是 Erlang 的重要組成部分。首先,讓我們看看如何通過(guò)實(shí)現(xiàn) factorial 程序來(lái)實(shí)現(xiàn)簡(jiǎn)單的遞歸。

實(shí)例

-module(helloworld). 
-export([fac/1,start/0]). 

fac(N) when N == 0 -> 1; 
fac(N) when N > 0 -> N*fac(N-1). 

start() -> 
   X = fac(4), 
   io:fwrite("~w",[X]).

關(guān)于上述程序,需要注意以下幾點(diǎn):

  • 我們首先定義一個(gè)名為 fac(N) 的函數(shù)。

  • 我們可以通過(guò)遞歸調(diào)用fac(N)來(lái)定義遞歸函數(shù)。

上面程序的輸出是:

輸出

24

遞歸的實(shí)用方法

在本節(jié)中,我們將詳細(xì)了解遞歸的不同類型及其在Erlang中的用法。

長(zhǎng)度遞歸

遞歸的一種更實(shí)用的方法可以從一個(gè)用于確定列表長(zhǎng)度的簡(jiǎn)單示例中看出。一個(gè)列表可以有多個(gè)值,如[1,2,3,4]。讓我們使用遞歸來(lái)看看如何得到一個(gè)列表的長(zhǎng)度。

-module(helloworld). 
-export([len/1,start/0]). 

len([]) -> 0; 
len([_|T]) -> 1 + len(T). 

start() -> 
   X = [1,2,3,4], 
   Y = len(X), 
   io:fwrite("~w",[Y]).

關(guān)于上述程序,需要注意以下幾點(diǎn):

  • 如果列表為空,則第一個(gè)函數(shù)len([])用于特殊情況下的條件。

  • [H|T] 模式來(lái)匹配一個(gè)或多個(gè)元素的列表,如長(zhǎng)度為1的列表將被定義為 [X|[]],而長(zhǎng)度為 2 的列表將被定義為 [X|[Y|[]]] 。  

  • 注意,第二元素是列表本身。這意味著我們只需要計(jì)數(shù)第一個(gè),函數(shù)可以調(diào)用它本身在第二元素上。在列表給定每個(gè)值的長(zhǎng)度計(jì)數(shù)為 1 。

上面程序的輸出將是

4

尾遞歸

要了解尾遞歸的工作原理,讓我們了解上一節(jié)中的以下代碼如何工作。

語(yǔ)法

len([]) -> 0; 
len([_|T]) -> 1 + len(T).

1 + len (Rest)的答案需要找到 len (Rest)的答案。然后函數(shù) len (Rest)本身需要找到另一個(gè)函數(shù)調(diào)用的結(jié)果。添加的部分會(huì)堆疊起來(lái),直到找到最后一個(gè),然后才能計(jì)算出最終的結(jié)果。

尾部遞歸旨在通過(guò)在操作發(fā)生時(shí)減少它們來(lái)消除這種疊加操作。

為了實(shí)現(xiàn)這一點(diǎn),我們需要在函數(shù)中保留一個(gè)額外的臨時(shí)變量作為參數(shù)。前面提到的臨時(shí)變量有時(shí)被稱為 accumulator,用作存儲(chǔ)計(jì)算結(jié)果的地方,以限制調(diào)用的增長(zhǎng)。

讓我們看一下尾遞歸的一個(gè)實(shí)例

-module(helloworld).
-export([tail_len/1,tail_len/2,start/0]). 

tail_len(L) -> tail_len(L,0). 
tail_len([], Acc) -> Acc; 
tail_len([_|T], Acc) -> tail_len(T,Acc+1). 

start() -> 
   X = [1,2,3,4], 
   Y = tail_len(X), 
   io:fwrite("~w",[Y]).

上面程序的輸出是

4

重復(fù)(復(fù)本)

讓我們看一個(gè)遞歸的實(shí)例。這次讓我們編寫一個(gè)函數(shù),該函數(shù)將整數(shù)作為第一個(gè)參數(shù),然后將任何其他項(xiàng)作為第二個(gè)參數(shù)。然后,它將創(chuàng)建一個(gè)由整數(shù)指定的術(shù)語(yǔ)復(fù)本的列表。

讓我們看一下這樣的一個(gè)實(shí)例-

-module(helloworld). 
-export([duplicate/2,start/0]). 

duplicate(0,_) -> 
   []; 
duplicate(N,Term) when N > 0 ->
   io:fwrite("~w,~n",[Term]),
   [Term|duplicate(N-1,Term)]. 
start() -> 
   duplicate(5,1).

上面程序的輸出將是-

輸出

1,
1,
1,
1,
1,

列表反轉(zhuǎn)

在Erlang中可以使用遞歸沒(méi)有任何限制?,F(xiàn)在讓我們快速看一下如何使用遞歸來(lái)反轉(zhuǎn)列表的元素??梢允褂靡韵鲁绦騺?lái)完成此操作。

實(shí)例

-module(helloworld). 
-export([tail_reverse/2,start/0]). 

tail_reverse(L) -> tail_reverse(L,[]).

tail_reverse([],Acc) -> Acc; 
tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]).

start() -> 
   X = [1,2,3,4], 
   Y = tail_reverse(X), 
   io:fwrite("~w",[Y]).

上面程序的輸出將是-

輸出

[4,3,2,1]

關(guān)于上述程序,需要注意以下幾點(diǎn):

  • 我們?cè)俅问褂门R時(shí)變量的概念來(lái)將列表中的每個(gè)元素存儲(chǔ)在一個(gè)名為Acc的變量中。

    然后遞歸地調(diào)用tail_reverse,但這一次,我們確保最后一個(gè)元素先放到新列表中。

    然后遞歸地對(duì)列表中的每個(gè)元素調(diào)用tail_reverse。