復帰(Recursion)
23538 ワード
さいきかんすう
:ある関数から自分自身を呼び出して操作を実行する関数
再帰的な例示的なファクトリ問題の使用
工場の二つの条件
def factorial(n: int) -> int:
"""양의 정수 n의 팩토리얼을 구하는 과정"""
if n > 0:
return n * factorial(n - 1)
else:
return 1
if __name__ == '__main__':
n = int(input('출력할 팩토리얼 값을 입력하세요.: '))
print(f'{n}의 팩토리얼은 {factorial(n)}입니다.')
ユークリッドアーク除算(GCD,最大公約数を求める)問題
2つの整数値の最大公倍数を求める問題->2つの整数値がそれぞれ辺長の矩形がある場合、この矩形内に複数の正方形を埋め込むと、作成可能な矩形の中で最小の矩形辺長を探す意味と同じです
def gcd(x: int, y: int) -> int:
"""정숫값 x와 y의 최대 공약수를 반환"""
if y == 0:
return x
else:
return gcd(y, x % y)
if __name__ == '__main__':
print('두 정숫값의 최대 공약수를 구합니다.')
x = int(input('첫 번째 정숫값을 입력하세요.: '))
y = int(input('두 번째 정숫값을 입력하세요.: '))
print(f'두 정숫값의 최대 공약수는 {gcd(x, y)}입니다.')
->2つの整数値を指定した場合、大きい値を小さい値で割った場合、小さい値は最大公約数になります.再帰アルゴリズム解析
上から下への分析
一番上のボックスの中の関数呼び出しから始めて,次第に深く研究する分析方法
def recur(n: int) -> int:
"""순수한 재귀 함수 recur의 구현"""
if n > 0:
recur(n - 1)
print(n)
recur(n - 2)
x = int(input('정숫값을 입력하세요.: '))
recur(x)
n=3の場合関数で再帰呼び出しを複数回実行する関数
n=4の場合
4->recur(3)、print(4)#5番目の出力、////////////////////////recur(2)
->recur(2)、print(3)#3番目の出力、recur(1)#4番目の出力//////////////////recur(1)print(2)recur(0)
->recur(1)print(2)#2番目の出力recur(0)
->recur(0)print(1)#最初の出力recur(-1)
Output : 1 2 3 1 4 1 2
じょうほうこうぶんせき
上から下への分析とは逆に、下から上へ積み重ねて分析します.
recur()関数はnが正の値の場合にのみ実行されるため,まずrecur(1)がどのように処理されるかを考える.
recur(1)実行プロセス
運転
最終出力1万
再帰
recur(1)および2出力
再帰関数を非再帰的に実装する(末尾再帰を削除する)
末尾再帰(n-2)は「パラメータn-2として」の値を意味し、recur()関数を呼び出す
->すなわち、nの値をn-2に更新し、関数の開始点を返します.
def recur(n: int) -> int:
"""꼬리 재귀를 제거한 함수 recur"""
while n > 0:
recur(n - 1)
print(n)
n = n - 2
x = int(input('정수값을 입력하세요.: '))
recur(x)
再帰の削除
n値を出力する前にrecur(n-1)を実行する必要があるため、n=4の場合、recur(3)の処理が完了するまで4をある位置に保存し、スタックを使用する必要があります!
from stack import Stack # stack.py의 Stack 클래스를 임포트
def recur(n: int) -> int:
"""재귀를 제거한 함수 recur"""
s = Stack(n)
while True:
if n > 0:
s.push(n) # n 값을 푸시
n = n - 1
continue
if not s.is_empty(): # 스택이 비어 있지 않으면
n = s.pop() # 저장하고 있는 값을 n에 팝
print(n)
n = n - 2
continue
break
x = int(input('정수값을 입력하세요.: '))
recur(x)
分割とマージ
1つのアルゴリズムで、問題をいくつかの部分に分けて解き、それから合併して問題の答えを得る.
問題設計要領
1)Divide:問題が分割可能であれば2つ以上の問題に分けられる.
2)Conquer:分割の問題がまだ分割可能であれば再分割
3)Combine:Conquerは問題を統合して元の問題の答えを得る
ハノイの塔問題
ハノイの塔は小円盤上、大円盤下のルールを守り、3本の柱を利用して円盤を移動する問題がある.
3つのディスクの移動プロセス全体
3つのディスクの場合
2つのディスクの場合
4つのディスクの場合
def move(no: int, x: int, y: int) -> None:
"""원반을 no개를 x 기둥에서 y 기둥으로 옮김"""
if no > 1:
move(no - 1, x, 6 - x - y)
print(f'원반 [{no}]을(를) {x}기둥에서 {y}기둥으로 옮깁니다.')
if no > 1:
move(no - 1, 6 - x - y, y)
print('하노이의 탑을 구현하는 프로그램입니다.')
n = int(input('원반의 개수를 입력하세요.: '))
move(n, 1, 3)
8皇后問題
8皇后問題は8×8サイズのチェス盤に8皇后を配置する問題です.1848年にマックス・ベッチェルが初めて提出した.この問題を一般化すると,NxNサイズのチェス盤にN個のクイーンを置くNクイーン問題である.
pos = [0] * 8 # 각 열에 배치한 퀸의 위치
flag_a = [False] * 8 # 각 행에 퀸을 배치했는지 체크
flag_b = [False] * 15 # 대각선 방향(↙↗)으로 퀸을 배치했는지 체크
flag_c = [False] * 15 # 대각선 방향( ↘↖)으로 퀸을 배치했는지 체크
def put() -> None:
"""각 열에 배치한 퀸의 위치를 출력"""
for i in range(8):
print(f'{pos[i]:2}', end='')
print()
def set(i: int) -> None:
"""i 열의 알맞은 위치에 퀸을 배치"""
for j in range(8):
if( not flag_a[j] # j행에 퀸이 배치 되지 않았다면
and not flag_b[i + j] # 대각선 방향(↙↗)으로 퀸이 배치 되지 않았다면
and not flag_c[i - j + 7]): # 대각선 방향( ↘↖)으로 퀸이 배치 되지 않았다면
pos[i] = j # 퀸을 j행에 배치
if i == 7: # 모든 열에 퀸을 배치하는 것을 완료
put()
else:
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = True
set(i + 1) # 다음 열에 퀸을 배치
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = False
set(0) # 0열에 퀸을 배치
Reference
この問題について(復帰(Recursion)), 我々は、より多くの情報をここで見つけました https://velog.io/@eclat12450/재귀Recursionテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol