English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Erlang 재귀

재귀는 Erlang의 중요한 부분입니다. 먼저 factorial 프로그램을 통해 간단한 재귀를 구현해 보겠습니다.

예시

-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]).

위 프로그램에 대해 주의해야 할 몇 가지 사항이 있습니다:

  • 우리는 먼저 fac(N)라는 함수를 정의합니다.

  • 우리는 fac(N)를 호출하여 재귀 함수를 정의할 수 있습니다.

위 프로그램의 출력은 다음과 같습니다:

출력

24

재귀의 실용적인 방법

이 장에서는 재귀의 다양한 유형과 Erlang에서의 사용법을 자세히 설명할 것입니다.

길이 재귀

재귀의 하나의 더 실용적인 방법은 목록 길이를 결정하는 간단한 예제에서 볼 수 있습니다. 목록에는 여러 가지 값이 있을 수 있습니다. 예를 들어 [1,2,3,4]。리스트의 길이를 얻는 방법을 재귀로 보여드리겠습니다.

-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]).

위 프로그램에 대해 주의해야 할 몇 가지 사항이 있습니다:

  • 리스트가 비어 있으면, 특별한 경우의 조건에서 사용되는 첫 번째 함수 len([])가 필요합니다.

  • [H|T] 패턴으로 일정 수의 요소를 가진 리스트를 매칭하면 길이는1의 리스트는 [X|[]]로 정의되며, 길이는 2 의 리스트는 [X|[Y|[]]]로 정의됩니다.  

  • 주의하시오, 두 번째 요소는 리스트 자체입니다. 이는 첫 번째 요소만 카운트가 필요하다는 것을 의미하며, 함수는 두 번째 요소에서 자기 자신을 호출할 수 있습니다. 각 값의 길이를 카운트하는 경우 1 .

위 프로그램의 출력은 다음과 같습니다:

4

tail recursion

tail recursion의 작동 방식을 이해하기 위해, 이전 장에서 언급된 다음 코드가 어떻게 작동하는지 알아보겠습니다.

문법

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

1 + len (Rest)의 답은 len (Rest)의 답을 찾아야 합니다. 그런 다음, 함수 len (Rest) 자체가 다른 함수 호출의 결과를 찾아야 합니다. 추가된 부분은 쌓여가며, 마지막에 찾아낼 수 있게 되면 최종 결과를 계산할 수 있습니다.

尾部递归는 작업이 발생할 때마다 그들을 줄이며 이러한 쌓임을 제거하는 목적을 가지고 있습니다.

이를 위해, 함수에서 추가적인 일시적인 변수를 매개변수로 유지해야 합니다. 이전에 언급된 일시적인 변수는 때로는 accumulator라고 불리며, 호출의 증가를 제한하는 곳으로 사용됩니다.

让我们看一下尾递归의 예제

-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

복제(복제)

让我们看一个递归의 예제. 이번에는 함수를 작성해 보겠습니다. 이 함수는 정수를 첫 번째 매개변수로, 그 다음에 다른 항목을 두 번째 매개변수로 사용합니다. 그런 다음, 정수로 지정된 테르미널 복本的 리스트를 생성합니다.

让我们看一下这样的一个实例-

-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,

리스트 반전

Erlang에서는 제한 없이 재귀를 사용할 수 있습니다. 지금让我们快速看一下如何使用递归来反转列表의 요소를 보여드리겠습니다. 이 작업을 완료하기 위해 다음 프로그램을 사용할 수 있습니다.

예시

-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]

위 프로그램에 대해 주의해야 할 몇 가지 사항이 있습니다:

  • Acc라는 이름의 변수에 목록의 각 요소를 저장하는 데 임시 변수 개념을 다시 사용합니다.

    그런 다음 tail_reverse를 재귀적으로 호출하지만, 이번에는 마지막 요소를 먼저 새 목록에 넣습니다.

    그런 다음 목록의 각 요소에 대해 tail_reverse를 재귀적으로 호출합니다.