10~11. 반복함수와 재귀함수(팩토리얼 / 피보나치 수열) ) [프로젝트명 : Tutorial10, 11]
9. 반복함수와 재귀함수(팩토리얼/ 피보나치 수열) ( Tutorial10, 11)
반복함수는 while 혹은 for문법을 이용해서 문제를 해결하는 함수다.
재귀함수는 자신의 함수 내부에서 자기 자신을 스스로 호출함으로써 재귀적으로 문제를 해결하는 함수다.
(Tutorial10)
[1] 반복함수로 팩토리얼을 구현해보자
1. int를 하나 받아서 int를 반환하는 팩토리얼 함수를 만들자.
- 로컬 변수 sum에 1을 넣어 초기화 한 다음, for문을 통해서 sum에다가 2부터 i를 받은 숫자까지 곱해서 넣어주자.
//5! = 5 * 4 * 3 * 2 * 1
public static int factorial(int number) {
int sum = 1;
for ( int i = 2; i<=number ; i++) {
sum *= i;
}
return sum;
}
2. 메인함수에서 출력시켜보자
public static void main(String[] args) {
System.out.println("10팩토리얼은 "+factorial(10)+ "입니다.");
}
[2] 재귀함수로 팩토리얼을 구현해보자.
1. 받은 값이 1일 때만 예외적으로, 1을 return해서 마무리 짓는다.
왜냐하면, 속에 똑같은 매쏘드()가 들어가는데, -1씩 줄여서 대입할 것이기 때문에, 마지막 1은 바로 1을 리턴하도록 한다
재귀함수는 계속 자신을 호출하므로, 마지막에는 상수로 마무리대응 해야한다.
2. return할 때, 받은 수 * 매쏘드( 받은수 -1 ); 을 반환해서, 받은수 -1 이 또 한바퀴 돌도록 한다. 1이 되면 그냥 1이 return되서 끝난다.
- 핵심은 -1 씩 줄여가다가 마지막 종점 1에서는 재귀함수를 호출 안하고, 값 1을 반환해서 끝낸다.
- 핵심은 5! = 5 * 4!로 같으며, 팩토리얼 속에 또 -1의 팩토리얼이 담겨져 있으니까, 재귀함수로 표현 가능하다.
f(5) = 5 * f(4)
//5! = 5 * 4!
public static int factorial(int number) {
if(number ==1)
return 1;
else
return number * factorial(number-1);
}
(Tutorial11)
[3] 반복함수로 피보나치 수열을 구현해보자.
- 피보나치 수열은 연속된 두 수를 더해서 다음 수가 나오는 수열을 말한다.(// 1, 1, 2, 3, 5, 8, ...)
- k번 째 수가 무엇인지 알아내는 함수를 만들 것이다.
1. 첫째항 1과 둘째항 1을 미리 선언해준다. 잘못된 경우에 -1을 반환하도록 result도 만들어준다.
(피보나치수열은 초기항 a1, a2는 기본적으로 주어진다)
2. if /else if 에다가는 첫째항, 둘째항이 입력되면 바로 반환하도록 만들고 / 나머지 3번째항 이상인 경우 else에다가 아래와 같이 코드를 작성해야한다.
- for문 2 <= i < number 까지 돌면서,
<2부터 시작하는 이유는, number가 3이라고 가정해보면, i=2일때만 for문이 작동하므로 a1 + a2 만 계산한 a3가 리턴된다
만약 number가 4라면, i=2일 때 다음계산을 위해, a2가 one에 / a3가 two에 들어가고, 마지막 i=3이면 a2+ a3 가 result에 담겨서 리턴되기 때문>
i = 2 일때, 초기항 2개를 더해서 result에 넣어준다. (one + two)
다음계산을 위해서, one에다가는 오른쪽으로 한칸 옮겨지므로, two를 대입해준다
two에다가는 오른족으로 한칸 옮겨지므로, one+two값인 result를 넣어준다.
i = 3 일때, 미리 옮겨진 one 과 two를 더해서 result에 더한다. 그리고 오른쪽으로 한칸씩 one과 two를 옮긴 값을 대입해 놓는다.
...
i=number-1 일때, number항 직전 2개의 항인 one과 two를 더해서 result에 넣는다. 그리고 다음계산을 위해 오른쪽으로 옮겨놓지만 사용되진 않음.
public static int fibonacci(int number) {
int one=1;
int two=1;
int result = -1;
if(number == 1)
{
return one;
}
else if(number == 2) {
return two;
}
else{
for(int i = 2; i < number ; i++) {
result = one + two; // number 직전까지 아래에서 one과 two를 옮겨놓았다.
one = two; // 수열 오른쪽으로 한칸씩 다음 계산을 위해, 옮겨놓는 작업.
two = result;
}
return result;
}
}
3. 출력해보자.
public static void main(String[] args) {
System.out.println("피보나치 수열의 10번째 원소는 "+fibonacci(10)+"입니다.");
}
[4] 재귀함수로 피보나치 수열을 구현해보자. 훨씬 간단해진다.
- 핵심은 n-1씩 해가면서, 줄여가는 것이다. 그리고 마지막 종점지에는 상수를 이용해서 리턴해줘야한다.
- 팩토리얼 함수와 차이점은 n-1뿐만 아니라 n-2도 있으니, 2개의 초기항이 존재해야한다.
1. 첫번째, 2번째 항에 대해서는 if문으로 바로 return1을 해주자.
2. 3번재 이상부터는, return값에 f(n-2) + f(n-1)만 해주면 된다.
public static int fibonacci(int number) {
if(number ==1)
{
return 1;
}else if(number==2) {
return 1;
}else {
return fibonacci(number-2) + fibonacci(number-1) ;
}
}
*** 반복함수와 달리 재귀함수의 피보나치 수열은 f(49) 계산시, f(48) + f(47)이 계산되지만,
f(48)계산시에도 f(47) + f(46)이 계산되므로, 반복되는 계산이 기하급수적으로 많아 진다.
재귀함수를 사용할 때, 훨씬 비효율적인 계산을 하므로, 주의해서 계산해야한다. 실제로 f(50)을 물어보면, 계산값이 안나온다.
'Java > 기초 튜토리얼' 카테고리의 다른 글
13. 다차원 배열 - 2차원 배열 (2차원배열에 랜덤정수 넣고 출력) [ Tutorial 13] (0) | 2018.02.20 |
---|---|
12. 배열(Array) (입력받은 배열의 최대값/ 100개의 랜덤 정수의 평균) [ Tutorial12 ] (0) | 2018.02.19 |
8~9. 사용자 정의 함수(최대공약수/ k번째 약수/ 마지막문자 뽑기/ 최대값) [프로젝트명 : Tutorial8, 9] (0) | 2018.02.18 |
7. 기본 입출력 / 파일 입출력 (Scanner/file 입출력) [프로젝트명 : Tutorial7] (0) | 2018.02.18 |
5~6. 조건문 & 반복문(contains/점수조건/equals/합/삼각형/원 만들기) [프로젝트명 : Tutorial5, 6] (0) | 2018.02.08 |