고차 함수와 재귀 함수는 서로 다른 개념이지만 종종 함께 사용될 수 있다.
이 두 가지 개념은 함수형 프로그래밍 스타일에서 자주 사용되며, 서로를 보완하고 유연하게 코드를 작성할 수 있는데 기여한다.
고차 함수와 재귀 함수의 연관성
1. 재귀 함수를 인자로 받는 고차 함수
- 고차 함수는 다른 함수를 인자로 받을 수 있다.
- 이때, 재귀 함수를 인자로 받는 고차 함수를 작성할 수 있다.
- 예를 들어, 고차 함수가 재귀 함수를 인자로 받아서 재귀 호출을 추상화하고 조작하는 역할을 할 수 있다.
2. 재귀 함수 내에서의 고차 함수 사용
- 재귀 함수 내에서도 고차 함수를 사용할 수 있다.
- 재귀 함수의 기본 케이스와 재귀 케이스를 구현하는 과정에서 다른 함수를 호출하거나 반환할 수 있다.
- 이렇게 함으로써 재귀적인 작업을 보다 모듈화하고 추상화할 수 있다.
# 고차 함수를 이용한 재귀 함수
def apply_recursive(func, n):
if n == 0:
return 1
else:
return func(n) * apply_recursive(func, n - 1)
# 팩토리얼 계산하는 재귀 함수
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
# 팩토리얼 계산하는 고차 함수를 이용한 팩토리얼 계산
print(apply_recursive(factorial, 5)) # 출력: 120
- 위의 예시에서는 `apply_recursive`라는 고차 함수를 정의하여 재귀적인 계산을 추상화한다.
- 이 함수는 다른 함수 `func`와 정수 `n`을 인자로 받아서, `func` 함수를 이용하여 재귀적으로 값을 계산한다.
- 이러한 방식으로 고차 함수와 재귀 함수가 함께 사용되어 유연하고 모듈화된 코드를 작성할 수 있다.
고차 함수(Higher-Order Functions)
함수를 인자로 받는 고차 함수
- 고차 함수는 다른 함수를 인자로 받아들이고, 이를 이용하여 또 다른 동작을 수행한다.
- 이를 통해 우리는 코드를 보다 추상적으로 만들고, 함수의 재사용성을 높일 수 있다.
- 이러한 접근 방식은 다양한 디자인 패턴에서 사용된다.
예를 들어, 우리는 여러 가지 연산을 수행하는 함수 `apply_operation`을 가지고 있다. 이 함수는 함수 `func`와 두 개의 인자 `x`, `y`를 받아들인다. 우리는 이러한 함수를 이용하여 덧셈이나 곱셈과 같은 연산을 쉽게 수행할 수 있다.
def create_adder(n):
def adder(x):
return x + n
return adder
add_five = create_adder(5)
print(add_five(10)) # 출력: 15
함수를 반환하는 고차 함수
- 고차 함수는 함수를 생성하고 반환한다.
- 이를 통해 우리는 필요에 따라 함수를 동적으로 생성하고 반환할 수 있다.
- 이는 클로저(Closure)를 만들거나 파셜 함수(Partial Functions)를 생성하는 데 유용하다.
클로저(Closure)란?
클로저는 함수와 그 함수가 선언될 때의 환경을 함께 저장하여, 나중에 사용될 때에도 그 환경을 기억하고 참조할 수 있게 해주는 개념
주로 함수 내부에서 정의된 내부 함수가 외부 함수의 변수나 매개변수를 참조할 때 클로저가 생성된다.
파셜 함수(Partial Function)란?
파셜 함수는 함수의 일부 인자를 고정하여 새로운 함수를 생성하는 개념
파셜 함수는 함수형 프로그래밍에서 매우 유용하며, 함수를 조합하고 재사용하기 쉽도록 하게 한다.
예를 들어, 우리는 특정한 값을 더하는 함수를 생성하는 `create_adder` 함수를 가지고 있다. 이 함수는 값을 받아들이고, 해당 값을 더하는 새로운 함수를 반환한다. 이렇게 반환된 함수는 기존의 `create_adder` 함수에서 사용한 값에 접근할 수 있다.
def factorial(n):
# 기본 케이스: n이 1 이하일 때
if n <= 1:
return 1
# 재귀 케이스: n! = n * (n-1)!
else:
return n * factorial(n - 1)
print(factorial(5)) # 출력: 120
재귀 함수(Recursive Functions)
1. 기본 케이스(Base Case)
- 재귀 함수는 반드시 기본 케이스를 가져야 한다.
- 이는 함수가 재귀 호출을 종료하는 조건
- 기본 케이스가 없으면 함수는 무한히 호출되며, 스택 오버플로우(Stack Overflow)가 발생할 수 있다.
예를 들어, 팩토리얼을 계산하는 재귀 함수에서 기본 케이스는 `n`이 1 이하일 때입니다.
2. 재귀 케이스(Recursive Case)
- 재귀 함수의 재귀 케이스는 함수가 자기 자신을 호출하는 부분을 말한다.
- 이를 통해 우리는 주어진 문제를 더 작은 부분 문제로 분해하고 해결할 수 있다.
예를 들어, 팩토리얼을 계산하는 재귀 함수에서 재귀 케이스는 `n! = n * (n-1)!`의 형태를 가집니다.
def factorial(n):
# 기본 케이스: n이 1 이하일 때
if n <= 1:
return 1
# 재귀 케이스: n! = n * (n-1)!
else:
return n * factorial(n - 1)
print(factorial(5)) # 출력: 120
- 재귀 함수는 일반적으로 반복적인 문제를 해결하기 위해 사용된다.
- 그러나 재귀 호출이 너무 깊어지면 스택 오버플로우가 발생할 수 있으므로 주의해야 한다.
'CS' 카테고리의 다른 글
오버플로우(Overflow) (0) | 2024.04.05 |
---|---|
동기화와 교착상태 (1) | 2024.04.04 |
SQLite (0) | 2024.04.02 |
UUID 개념 및 생성 방법 (0) | 2024.04.01 |
람다(lambda) 함수 (1) | 2024.03.21 |
고차 함수와 재귀 함수는 서로 다른 개념이지만 종종 함께 사용될 수 있다.
이 두 가지 개념은 함수형 프로그래밍 스타일에서 자주 사용되며, 서로를 보완하고 유연하게 코드를 작성할 수 있는데 기여한다.
고차 함수와 재귀 함수의 연관성
1. 재귀 함수를 인자로 받는 고차 함수
- 고차 함수는 다른 함수를 인자로 받을 수 있다.
- 이때, 재귀 함수를 인자로 받는 고차 함수를 작성할 수 있다.
- 예를 들어, 고차 함수가 재귀 함수를 인자로 받아서 재귀 호출을 추상화하고 조작하는 역할을 할 수 있다.
2. 재귀 함수 내에서의 고차 함수 사용
- 재귀 함수 내에서도 고차 함수를 사용할 수 있다.
- 재귀 함수의 기본 케이스와 재귀 케이스를 구현하는 과정에서 다른 함수를 호출하거나 반환할 수 있다.
- 이렇게 함으로써 재귀적인 작업을 보다 모듈화하고 추상화할 수 있다.
# 고차 함수를 이용한 재귀 함수
def apply_recursive(func, n):
if n == 0:
return 1
else:
return func(n) * apply_recursive(func, n - 1)
# 팩토리얼 계산하는 재귀 함수
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
# 팩토리얼 계산하는 고차 함수를 이용한 팩토리얼 계산
print(apply_recursive(factorial, 5)) # 출력: 120
- 위의 예시에서는 `apply_recursive`라는 고차 함수를 정의하여 재귀적인 계산을 추상화한다.
- 이 함수는 다른 함수 `func`와 정수 `n`을 인자로 받아서, `func` 함수를 이용하여 재귀적으로 값을 계산한다.
- 이러한 방식으로 고차 함수와 재귀 함수가 함께 사용되어 유연하고 모듈화된 코드를 작성할 수 있다.
고차 함수(Higher-Order Functions)
함수를 인자로 받는 고차 함수
- 고차 함수는 다른 함수를 인자로 받아들이고, 이를 이용하여 또 다른 동작을 수행한다.
- 이를 통해 우리는 코드를 보다 추상적으로 만들고, 함수의 재사용성을 높일 수 있다.
- 이러한 접근 방식은 다양한 디자인 패턴에서 사용된다.
예를 들어, 우리는 여러 가지 연산을 수행하는 함수 `apply_operation`을 가지고 있다. 이 함수는 함수 `func`와 두 개의 인자 `x`, `y`를 받아들인다. 우리는 이러한 함수를 이용하여 덧셈이나 곱셈과 같은 연산을 쉽게 수행할 수 있다.
def create_adder(n):
def adder(x):
return x + n
return adder
add_five = create_adder(5)
print(add_five(10)) # 출력: 15
함수를 반환하는 고차 함수
- 고차 함수는 함수를 생성하고 반환한다.
- 이를 통해 우리는 필요에 따라 함수를 동적으로 생성하고 반환할 수 있다.
- 이는 클로저(Closure)를 만들거나 파셜 함수(Partial Functions)를 생성하는 데 유용하다.
클로저(Closure)란?
클로저는 함수와 그 함수가 선언될 때의 환경을 함께 저장하여, 나중에 사용될 때에도 그 환경을 기억하고 참조할 수 있게 해주는 개념
주로 함수 내부에서 정의된 내부 함수가 외부 함수의 변수나 매개변수를 참조할 때 클로저가 생성된다.
파셜 함수(Partial Function)란?
파셜 함수는 함수의 일부 인자를 고정하여 새로운 함수를 생성하는 개념
파셜 함수는 함수형 프로그래밍에서 매우 유용하며, 함수를 조합하고 재사용하기 쉽도록 하게 한다.
예를 들어, 우리는 특정한 값을 더하는 함수를 생성하는 `create_adder` 함수를 가지고 있다. 이 함수는 값을 받아들이고, 해당 값을 더하는 새로운 함수를 반환한다. 이렇게 반환된 함수는 기존의 `create_adder` 함수에서 사용한 값에 접근할 수 있다.
def factorial(n):
# 기본 케이스: n이 1 이하일 때
if n <= 1:
return 1
# 재귀 케이스: n! = n * (n-1)!
else:
return n * factorial(n - 1)
print(factorial(5)) # 출력: 120
재귀 함수(Recursive Functions)
1. 기본 케이스(Base Case)
- 재귀 함수는 반드시 기본 케이스를 가져야 한다.
- 이는 함수가 재귀 호출을 종료하는 조건
- 기본 케이스가 없으면 함수는 무한히 호출되며, 스택 오버플로우(Stack Overflow)가 발생할 수 있다.
예를 들어, 팩토리얼을 계산하는 재귀 함수에서 기본 케이스는 `n`이 1 이하일 때입니다.
2. 재귀 케이스(Recursive Case)
- 재귀 함수의 재귀 케이스는 함수가 자기 자신을 호출하는 부분을 말한다.
- 이를 통해 우리는 주어진 문제를 더 작은 부분 문제로 분해하고 해결할 수 있다.
예를 들어, 팩토리얼을 계산하는 재귀 함수에서 재귀 케이스는 `n! = n * (n-1)!`의 형태를 가집니다.
def factorial(n):
# 기본 케이스: n이 1 이하일 때
if n <= 1:
return 1
# 재귀 케이스: n! = n * (n-1)!
else:
return n * factorial(n - 1)
print(factorial(5)) # 출력: 120
- 재귀 함수는 일반적으로 반복적인 문제를 해결하기 위해 사용된다.
- 그러나 재귀 호출이 너무 깊어지면 스택 오버플로우가 발생할 수 있으므로 주의해야 한다.
'CS' 카테고리의 다른 글
오버플로우(Overflow) (0) | 2024.04.05 |
---|---|
동기화와 교착상태 (1) | 2024.04.04 |
SQLite (0) | 2024.04.02 |
UUID 개념 및 생성 방법 (0) | 2024.04.01 |
람다(lambda) 함수 (1) | 2024.03.21 |