⇒ 이유 : 함수를 계속 호출시 가장 마지막에 호출하기 함수가 먼저 수행을 끝내야 그 앞의 함수 호출이 종료되기 때문
스택 자료구조를 활용해야 하는 상당수는 재귀 함수를 이용해서 간편하게 구현 가능
파이썬 예제
문자열이 무한히 출력하다가 재귀의 최대 깊이 초과시 오류가 뜸
defrecursive_function(): # def는 함수를 만들 때 사용하는 예약어print('재귀 함수를 호출합니다.')recursive_function()recursive_function()
🍇 자연수(양의 정수)
1은 자연수
자연수 n의 바로 다음 정수도 자연수이다.
🍇정렬알고리즘(병합, 퀵 정렬)
이진검색트리 활용되는 알고리즘 이다.
접근 방식
팩토리얼 구하기
음이 아닌 정수의 팩토리얼값
0!=1n>0 이면 n!= n x (n-1)!5!5x4x3x2x1=120int result =0for(int i =5; i<0;i--){result = result * i;}
재귀호출(recursive call)
자신과 똑같은 구조의 메소드를 호출하는 방식
문제) 0 이상의 두정수 n, m 이 주어졌을때 n 구하시오
재귀 접근
상태 정의
재귀는 부분문제를 해결하기 위한 풀이 방법
부분문제는 각각 하나의 명확한 문제를 나타내어 하나의 답을 낼 수 있어야 한다.
답을 내는데는 입력되는 변수
이렇게 답을 결정하는 변수들을 상태(state)
하나의 상태에 대한 답을 찾는 문제
2개의 변수가 있으므로, 상태(n,m) 정의하여 표기
종료 조건
부분 문제들을 생성하여 해결해 나가다가 언젠가는 종료해야 한다.
답이 나오는 상태를 검사하여 반환할 수 있도록 종료조건
n의 0제곱을 구할때 (m=0) 답 1
0의 m제곱 구할때(n=0) 1
1의 m제곱 (n= 1) 1
(n,0) =1(0,m) =1(1,m) =1(n,m) = n*(n,m-1)
🍇 거듭 제곱 값 구하기
importjava.util.Scanner;publicclasspowerEx {privatestaticintpower(int n,int m){if (m ==0 ) return1;if (n ==0) return1;if (n==0) return1;return n*power(n, m-1); }publicstaticvoidmain(String[] args){Scanner in =newScanner(System.in);int n =in.nextInt();int m =in.nextInt();int result =power(n, m);System.out.printf("%d의 %d 거듭제곱 값 : %d", n, m, result); }}
🍇 최대 공약수 구하기
importjava.util.Scanner;publicclassGcd {privatestaticintgCD(int x,int y){if(y ==0) return x;elsereturngCD(y, x%y); }publicstaticvoidmain(String[] args){Scanner in =newScanner(System.in);int n =in.nextInt();int m =in.nextInt();int result =gCD(n, m);System.out.printf("%d의 %d 최대공약수 : %d", n, m, result); }}
🍇 하노의의 탑
세 개의 기둥과 원판들이 주어졌을 때, 한 기둥에서 다른 기둥으로 모든 원판을 옮기는 문제이며, 원판들은 크기에 따라 다르며, 큰 원판 위에 작은 원판이 올라가야 한다.
핵심 : 목표는 모든 원판을 기둥 A에서 기둥 C로 옮기는 것
문제 : https://school.programmers.co.kr/learn/courses/30/lessons/12946
importjava.util.ArrayList;importjava.util.List;classSolution {privateList<int[]> hanoi(int n,int from,int to){if(n ==1) returnList.of(newint[] {from, to}); //종료조건 n==1 일때 from to 이동만 시켜라//점화식 구현int empty =6- from - to;List<int[]> result =newArrayList<>();result.addAll(hanoi(n-1,from,empty));result.addAll(hanoi(1,from,to));result.addAll(hanoi(n-1,empty,to));return result; }publicint[][] solution(int n) {returnhanoi(n,1,3).toArray(newint[0][]); }}
다른 사람 코드
importjava.util.Arrays;classHanoi {publicint[][] hanoi(int n) {// 2차원 배열을 완성해 주세요.int[][] answer = {{1,3}};System.out.println(n);return answer; }// 아래는 테스트로 출력해 보기 위한 코드입니다.publicstaticvoidmain(String[] args) {Hanoi h =newHanoi();System.out.println(Arrays.toString(h.hanoi(2))); }}
🍇 하노의 원반의 개수
하노이 탑의 동작원리를 알 수 있음
// 하노이의 탑packagerecurive;importjava.util.Scanner;classHanoi {//--- no개의 원반을 x번 기둥에서 y번 기둥으로 옮김 ---//staticvoidmove(int no,int x,int y) {if (no >1)move(no -1, x,6- x - y);System.out.printf("원반[%d]를 %d번 기둥에서 %d번 기둥으로 옮김\n", no, x, y);if (no >1)move(no -1,6- x - y, y); }publicstaticvoidmain(String[] args) {Scanner stdIn =newScanner(System.in);System.out.println("하노이의 탑");System.out.print("원반의 개수 : ");int n =stdIn.nextInt();move(n,1,3); // 제 1 기둥에 쌓인 n개를 제 3 기둥으로 옮김 }}
🍇 모음 사전
해설 : https://ksb-dev.tistory.com/273
A, E, I, O, U 만을 사용하여 5자리 이내의 문자를 만들고, 정렬하여 주어지는 문자가 몇 번째인지 반환해야 함
첫 번째 단어는 "A"이고, 두 번째 단어는 "AA"이며, 마지막 단어는 "UUUUU"
문제 : https://school.programmers.co.kr/learn/courses/30/lessons/84512
privateList<String>generate(String word){ //종료 조건, 점화식 구현}// 종료조건 5일 때, 바로 word 반환privateList<String>generate(String word){//종료 조건 , 점화식 구현 List<String> wrods =newArrayList<>();words.add(word);if(word.length() ==5) return words;//점화식 }
privateList<String>generate(String word){//종료 조건 , 점화식 구현 List<String> wrods =newArrayList<>();words.add(word);if(word.length() ==5) return words;//점화식 :사용될 수 있는 모든 문자를 words 붙여야 한다. privatestatic fianl char[] CHARS ="AEIOU".toCharArray(); }