재귀함수
-> 자기 자신을 호출하는 함수
스택 프레임에 대한 개념 :
예전에 C++로 스택프레임에 대해 공부하며 그렸던 그림인데 다시 보도록 하자.
(위 그림은 대략 이런 구조로 돌아간다는 거지 개념을 정확히 설명한 것은 아니다.)
이렇게하면 1 2 3 순서로 출력된다.
recur(x-1); 를 출력 뒤로 두면 3, 2, 1 순서로 출력된다.
스택 프레임에 대한 보다 정확한 개념은 위 그림을 참고하자
문제 1 :
자연수 N이 입력되면 재귀함수 이용해 1부터 N까지 출력하라 (3<=N<=10)
소스코드 :
import java.util.*;
import java.io.*;
public class Main {
public void recur(int n) {
if (n == 0) return;
else {
recur(n-1);
System.out.print(n+" ");
}
}
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
br.close();
T.recur(n);
}
}
문제 2 :
10진수 N이 입력되면 2진수로 변환하여 출력하는 프로그램을 작성하시오.
단, 재귀함수를 이용해 출력하여야 한다.
소스코드 :
import java.util.*;
import java.io.*;
public class Main {
public void recur(int n) {
if (n == 0) return;
else {
recur(n / 2);
System.out.print((n%2));
}
}
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
br.close();
T.recur(n);
}
}
문제 3 :
팩토리얼 문제
자연수 N이 입력되면 N!을 구하는 프로그램을 작성하시오.
소스코드 :
import java.util.*;
import java.io.*;
public class Main {
public int recur(int n) {
if(n == 1) return 1;
else return n*recur(n-1);
}
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
br.close();
bw.write(String.valueOf(T.recur(n)));
bw.flush();
bw.close();
}
}
풀이 :
1을 리턴받을때 스택에 있던 것들이 pop() 된다.
D(1)부터 pop() 된다.
문제 4 :
피보나치 재귀 (+ memoization)
N은 피보나치 수열의 총 항의 수이다.
N이 입력되면 해당 수 만큼 피보나치 수열을 출력하는 프로그램을 작성하여라.
소스코드 :
import java.util.*;
import java.io.*;
public class Main {
static int[] fibo;
public int recur(int n) {
if (fibo[n] > 0) return fibo[n];
if (n == 1) return fibo[n] = 1;
else if (n == 2) return fibo[n] = 1;
else return fibo[n] = recur(n-2) + recur(n-1);
}
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
br.close();
fibo = new int[n+1];
T.recur(n);
for(int i=1; i<=n; i++) bw.write(String.valueOf(fibo[i]+" "));
bw.flush();
bw.close();
}
}
풀이 :
if (fibo[n] > 0) return fibo[n];
코드로 인해 cut dege가 일어나 복잡도가 많이 개선된다.
+ 23년 2월 7일 추가
자바 코드
import java.util.*;
import java.io.*;
public class Main {
// 재귀 + memoization 이용한 풀이 (cut edge)
static int[] fibo;
public int recur(int n) {
if (fibo[n] > 0) return fibo[n];
if (n == 1) return fibo[n] = 1;
else if (n == 2) return fibo[n] = 1;
else return fibo[n] = recur(n-2) + recur(n-1);
}
public static void main(String[] args) throws IOException {
Main T = new Main();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
br.close();
fibo = new int[n+1];
T.recur(n);
bw.write(String.valueOf(fibo[n]));
bw.flush();
bw.close();
}
}
파이썬 코드
import sys
# 재귀 + memoization 이용한 풀이 (cut edge)
def recur(n):
if fibo[n] > 0 : return fibo[n]
if n == 1 :
fibo[n] = 1
return fibo[n]
elif n == 2 :
fibo[n] = 1
return fibo[n]
else :
fibo[n] = recur(n-2) + recur(n-1)
return fibo[n]
n = int(sys.stdin.readline())
fibo = [0 for i in range(n+1)]
recur(n)
print(fibo[n])
자바코드를 파이썬으로 작성할 시
if (n == 1) : return fibo[n] = 1 와 같이 코드를 작성하게 되면 오류가 발생하므로
if n == 1 :
fibo[n] = 1
return fibo[n]
와 같이 작성해주어야 한다.
'Java 코딩테스트 공부 > Java 알고리즘 공부' 카테고리의 다른 글
Recursive, Tree, Graph(DFS, BFS 기초) 3 - 이진트리, 상태트리 BFS (0) | 2023.03.15 |
---|---|
Recursive, Tree, Graph(DFS, BFS 기초) 2 - 이진트리, 부분집합 DFS (0) | 2022.11.12 |
Java 정렬, 이분검색과 결정알고리즘 3 (0) | 2022.11.04 |
Java 정렬, 이분검색과 결정알고리즘 2 (0) | 2022.09.03 |
Java 정렬, 이분검색과 결정알고리즘 1 (0) | 2022.09.02 |