[알고리즘] 순환(Recursion)의 개념과 기본 예제 1

2023. 6. 8. 15:20·Programming/Algorithm
인프런 무료 강의 권오흠교수님 '영리한 프로그래밍을 위한 알고리즘 강좌' 보면서 공부한 내용입니다.
부족한 내용이나 잘못된 내용은 댓글남겨주시면 감사하겠습니다!

출처 : https://inf.run/iezc

자기 자신을 참조하는 재귀함수의 순환에 대해 3일에 나눠서 학습할 예정이다.

먼저, 처음에는 아무런 조건을 주지 않은 상태에서 순환함수를 생성해보았다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-01
 * -> 무한 루프 발생
 */
package edu.recursion;

public class Recursion01_01 {
	public static void main(String[] args) {
		func();
	}
	
	public static void func(){
		System.out.println("Hello....");
		func();
	}
}

이렇게 아무런 조건 없이 자기 자신을 호출하는 재귀함수를 사용할 경우 무한 루프에 빠지게 된다.

 

다음 사진처럼 결국 무한루프에 벗어나지 못해 오류가 나는 모습을 볼 수 있다.

 

 

그럼 순환함수는 무조건 무한루프에 빠지게 되는 것 일까?

그럼 순환함수를 쓰는 의미가 없을 것이다.

이제부터 순환함수를 제대로 쓰는 법에 대해서 알아보자.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-02
 * 	조건을 걸어줄 경우 무한루프 발생하지 않음
 * 	-> Hello.... 4번 출력
 */
package edu.recursion;

public class Recursion01_02 {
	public static void main(String[] args) {
		func(4);
	}
	
	public static void func(int n){
		// Base case : 적어도 하나의 recursion에 빠지지 않는 경우가 존재해야 함
		if(n<=0){
			return;
		}
		// Recursive case : recursion을 반복하다보면 결국 base case로 수렴해야 함
		else{
			System.out.println("Hello....");
			func(n-1);
		}
	}
}

 

이렇게 Base case, Recursive case를 설정할 경우 무한루프에 빠지지 않고 재귀함수를 원하는 대로 잘 쓸 수가 있다.

재귀함수를 쓰는 순간 무한루프에 빠질 수 있기 때문에 탈출 할 수 있는 경우인 Base case를 적어주고 재귀함수를 호출 할 Recursive case를 써주면 된다.

 

이제부터 재귀함수, 즉 순환함수를 활용한 다양한 수학계산을 해보자.

다음은 0~n까지의 합을 구하는 함수이다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-03
 * 	1-n까지의 합 구함 
 * 	-> 10
 * 
 * [ 순환함수와 수학적귀납법 ]
 * func(int n)은 음이 아닌 정수 n에 대해서 0에서 n까지의 합을 계산
 * 
 * # 증명
 * 1. n=0인 경우 : n=0인 경우 0을 반환 -> 올바름
 * 2. 임의의 양의 정수 k에 대해서 n<k인 경우 0에서 n까지의 합을 올바르게 계산하여 반환한다고 가정
 * 3. n=k인 경우 고려. func은 먼저 func(k-1)호출하는데 2번의 가정에 의해서 0에서 k-1까지의 합이 올바로 계산되어 반환
 * 	   메서드 func은 그 값에 n을 더해서 반환.
 * 	   따라서 메서드 func은 0에서 k까지의 합을 올바르게 계산하여 반환
 */
package edu.recursion;

public class Recursion01_03 {
	public static void main(String[] args) {
		int result = func(4);
		System.out.println(result);
	}
	
	// 0~n까지의 합을 구하는 함수
	public static int func(int n){
		if(n<=0){
			return 0; // n=0일 경우 합은 0
		}
		else{
			// n이 0보다 크다면 0에서 n까지의 합은 0에서 n-1까지의 합에 n을 더한 것
			return n+func(n-1);
		}
	}
}

0~4까지의 합은 잘 알다싶이 10이다. main에서 func의 매개변수에 4를 넣어서 호출하는 순간,

func함수는 매개변수의 4가 0보다 큰지 비교를 한 후 0을 제외한 양수일 경우 현재 값인 4에 1을 뺸 3을 호출하고 4를 더해준다.

이렇게 반복을 하다보면 4+3+2+1+0이 되고 10이 출력하게 된다.

 

중, 고등학교 때 많이 공부했던 Factorial도 순환함수를 사용해서 구할 수 있다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-04
 * 	Factorial : n!
 * 	-> 11
 * 
 * [ Factorial ]
 * 0! = 1
 * n! = nx(n-1) 	n>0
 * 
 * [ 순환함수와 수학적귀납법 ]
 * factorial(int n)은 음이 아닌 정수 n에 대해서 n!을 계산
 * 
 * # 증명
 * 1. n=0인 경우 : n=0인 경우 1을 반환 -> 올바름
 * 2. 임의의 양의 정수 k에 대해서 n<k인 경우 n!을 올바르게 계산한다고 가정
 * 3. n=k인 경우 고려. 
 * 	   factorial은 먼저 factorial(k-1)호출하는데 2번의 가정에 의해서 (k-1)!이 올바로 계산되어 반환
 * 	   따라서 메서드 factorial은 k*(k-1)! = k!을 반환
 */
package edu.recursion;

public class Recursion01_04 {
	public static void main(String[] args) {
		int result = factorial(4);
		System.out.println(result);
	}
	
	public static int factorial(int n){
		if(n==0){
			return 1; 
		}
		else{
			return n+factorial(n-1);
		}
	}
}

교수님의 설명을 코드에 주석으로 달아놨고, 원리는 위와 동일하니 설명은 생략하겠다.

 

x의 승을 구하는 함수이다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-05
 * 	x^n
 * 	-> 16.0
 * 
 * [ x^n ]
 * x^0 = 1
 * x^n = x*x^n-1 	if n>0
 * 
 */
package edu.recursion;

public class Recursion01_05 {
	public static void main(String[] args) {
		double result = power(2, 4);
		System.out.println(result);
	}
	
	public static double power(double x, int n){
		if(n==0){
			return 1; 
		}
		else{
			return x*power(x, n-1);
		}
	}
}

 

다음은 피보나치 수를 구하는 함수이다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-06
 * fibonacci numbers - 피보나치 수
 * 	-> 3
 * 
 * [ 피보나치 수]
 * f0 = 0
 * f1 = 1
 * fn = fn-1 + fn-2		n>1
 * 
 */
package edu.recursion;

public class Recursion01_06 {
	public static void main(String[] args) {
		int result = fibonacci(4);
		System.out.println(result);
	}
	
	public static int fibonacci(int n){
		if(n<2){
			return n; 
		}
		else{
			return fibonacci(n-1) + fibonacci(n-2);
		}
	}
}

 

마지막은 최대공약수를 구하는 함수이다.

/*
 * 순환(Recursion)의 개념과 기본 예제 1-07
 * Euclid Method 최대공약수
 * 	-> 2.0
 * 
 * m >= n인 두 양의 정수 m과 n에 대해서 m이 n의 배수이면 gcd(m,n) =n이고, 
 * 그렇지 않으면 gcd(m, n) = gcd(n, m%n)이다.
 * 
 */
package edu.recursion;

public class Recursion01_07 {
	public static void main(String[] args) {
		double result = gcd(2,4);
		System.out.println(result);
	}
	
	public static double gcd(int m, int n){
		if(m<n){
			// swap m and n
			int tmp =m;
			m =n;
			n =tmp;
		}
		if(m%n == 0){
			return n;
		}
		else{
			return gcd(n, m%n);
		}
	}
}

 

교수님꼐서 설명을 너무 잘해주셔서 이해하는데 크게 어려움은 없었다. 

일단 알고리즘을 공부해야겠다고 생각은 들었는데 어떻게 시작을 해야할지 모를 경우, 아직 문제풀이를 할 자신이 없고 설명을 먼저 듣고 싶을 경우 이 강의를 추천한다.

 

특별한 일이 없을 경우 일주일에 3일씩 강의를 듣고 포스팅을 할 예정이다.

'Programming > Algorithm' 카테고리의 다른 글

[알고리즘] Recursion의 응용 : N-Queens  (0) 2023.06.15
[알고리즘] Recursion의 응용 - Counting Cells in a Blob  (0) 2023.06.14
[알고리즘] Recursion의 응용 - 미로 찾기  (0) 2023.06.13
[알고리즘] 순환(Recursion)의 개념과 기본 예제 3  (0) 2023.06.09
[알고리즘] 순환(Recursion)의 개념과 기본 예제 2  (0) 2023.06.08
'Programming/Algorithm' 카테고리의 다른 글
  • [알고리즘] Recursion의 응용 - Counting Cells in a Blob
  • [알고리즘] Recursion의 응용 - 미로 찾기
  • [알고리즘] 순환(Recursion)의 개념과 기본 예제 3
  • [알고리즘] 순환(Recursion)의 개념과 기본 예제 2
min_sol
min_sol
  • min_sol
    비글개발연구소🐾
    min_sol
  • 전체
    오늘
    어제
    • 분류 전체보기 (278)
      • Programming (128)
        • Algorithm (52)
        • JAVA (40)
        • GIS (5)
        • PyQt (10)
        • C# (11)
        • Mobile (6)
        • AI (4)
      • Backend (36)
        • Spring (14)
        • JSP (11)
        • Network (5)
      • Frontend (29)
        • React (11)
        • Vue (13)
        • Next.js (4)
      • Database (10)
        • PostgreSQL (1)
        • Oracle (8)
        • Elasticsearch (1)
      • DevOps (8)
        • Linux (7)
        • Mac (1)
      • Tools (31)
        • IntelliJ (1)
        • GitHub (10)
        • RPA (20)
      • Security (9)
      • etc (21)
        • ERROR (5)
        • 세미나 | 교육 (10)
        • 자격증 (1)
        • 일상 (2)
        • 2021 (2)
  • 인기 글

  • 태그

    생능출판
    RPA
    jsp
    PyQt5
    자동화
    계산기
    자바
    백준
    PyQt
    VUE
    알고리즘
    spring
    스윙
    코딩테스트
    연습문제
    이클립스
    vue.js
    자료구조
    명품자바에센셜
    Java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
min_sol
[알고리즘] 순환(Recursion)의 개념과 기본 예제 1
상단으로

티스토리툴바