2. 재귀를 활용한 계산

2023. 3. 30. 16:44·다양한 글들/자료구조와 알고리즘

2. 거듭 제곱 값 계산

<프로그램 2.2.1> 반복적인 거듭제곱 계산 프로그램

int slow_power(double x, int n){
    double r = 1.0;
    for(int i=0;i<n;i++){
    	r = r*x;
    }
    return r;
} // -> O(n)

<알고리즘 2.2.1> 순환적인 거듭제곱 계산

power(x,n)

if n=0
	return 1;
else if n이 짝수
	then return power(x^2,n/2);
else if n이 홀수
	then return x * power(x^2,(n-1)/2);
    
 (1) n이 짝수인 경우
 power(x,n) = power(x^2, n/2)
 			= (x^2)^(n/2)
            = x^2^(n/2)
            = x^n
 (2) n이 홀수인 경우
 power(x,n) = x * power(x^2,(n-1)/2)
 			= x*(x^2)^((n-1)/2)
            = x * x^(n-1)
            = x^n

<프로그램 2.2.2> 순환적인 거듭제곱 계산 프로그램

double power(double x, int n){
	if(n == 0) return 1;
    else if(n%2 == 0) return power(x*x, n/2);
    else return x*power(x*x,(n-1)/2);
} // -> O(logn)

-> 반복적인 거듭제급 계산보다 순환적인 거듭제곱 계산이 더 빠름, 순환을 호출할 때마다 문제의 크기가 약 절반으로 줄어들기 때문

Quiz

  1. power(2,6)과 같이 호출하였을 경우에 호출 체인을 그리시오
power(2,6) = power(4, 3) 
		   = 4 * power (16, 1) 
           = 4 * 16 * power(256 , 0)
           = 4 * 16 * 1
           = 4 * 16
           = 64
  1. 거듭제곱 값을 계산하는 함수를 다음의 순환적인 정의를 이용하여 작성하면 실행시간이 줄어드는가?
    xn={1ifn=0x∗x(n−1)ifn>0​
double power(double x, int n){
    if(n == 0)
        return 1;
    else
        return x * power(x, n - 1);
}

실행시간은 줄어들지 않는다 -> O(n)

3. 피보나치 수열의 계산

fib(n)=⎩⎪⎪⎨⎪⎪⎧​0n=01n=1fib(n−2)+fib(n−1)otherwise​

-> 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

<프로그램 2.3.1> 순환적인 피보나치 수열 계산 프로그램

#include <stdio.h>

int fib(int n){
	if(n == 0) return 0;
    else if(n == 1) retuern 1;
    else return fib(n-2) + fib(n-1);
}

fib(6) = fib(4) + fib(5)
	   = fib(2) + fib(3) + fib(3) + fib(4)
       = fib(0) + fib(1) + fib(1) + fib(2) + fib(1) + fib(2) + fib(2) + fib(3)
       = 0 + 1 + 1 + fib(0) + fib(1) + 1 + fib(0) + fib(1) + fib(0) + fib(1) + fib(1) + fib(2)
       = 0 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + fib(0) + fib(1)
       = 0 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 1
       = 8
  • 매우 이해하기 쉽지만 매우 비효율적, fib(6)으로 호출하였을 경우 fib(4)가 2번, fib(3)은 3번 계산됨. 이런 현상은 순환 호출이 깊어질수록 점점 심해짐

<프로그램 2.3.2> 반복적인 피보나치 수열 계산 프로그램

int fib_iter(int n){
	int tmp, current =1, last = 0;
    for(int i=2;i<=n;i++){
    	tmp = current;
        current += last;
        last = tmp;
    }
    return current;
}

Quiz

  1. fib(7)이 호출되었을 경우에 fib(4)는 몇번이나 중복 계산되는가? 3번 중복 계산됨
fib(7) = fib(5) + fib(6)
	   = fib(3) + fib(4) + fib(4) + fib(5)
       = fib(3) + fib(4) + fib(4) + fib(3) + fib(4)
  1. 반복적인 피보나치 수열 계산 함수의 시간복잡도? -> O(n)
  2. 순환적인 피보나치 수열 계산 함수의 대략적인 시간복잡도를 추리할 수 있겠는가? 하나의 함수 호출이 두 개의 함수 호출로 나누어진다는 점에 착안하라 -> O(2n)

4. 하노이탑 문제

하노이탑 조건

  • 한 번에 하나의 원판만 이동할 수 있다.
  • 맨 위에 있는 원판만 이동할 수 있다.
  • 크기가 작은 원판 위에 큰 원찬이 쌓일 수 없다.
  • 중간의 막대를 임시적으로 이용할 수 있으나 앞의 조건들을 지켜야 한다.

n개의 원판을 가지는 하노이탐 문제의 해답
1. A의 n-1개 원판을 B로 옮긴다.
2. A의 제일 밑에 있는 원판을 C로 옮긴다.
3. B의 n-1개 원판을 C로 옮긴다.

// 막대 from에 쌓여 있는 n개의 원찬을 막대 tmp를 사용하여 막대 to로 옮긴다.
void hanoi_tower(int n, char from, char tmp, char to){
	if(n == 1){
    	from에서 to로 원판을 옮긴다.
    }else{
    	1. from의 맨 밑에 있는 원판을 제외한 나머지 원판들을 tmp로 옮긴다.
        2. from에 있는 한 개의 원판을 to로 옮긴다.
        3. tmp의 원판들을 to로 옮긴다.
    }
}
  • 1, 3은 막대 위치만 달라졌을 뿐 원래 문제의 축소된 형태라는 것을 발견할 수 있음. 1은 to를 사용하여 from에서 tmp로 n-1개의 원판을 이동하는 문제이고, 3은 from을 사용하여 tmp에서 to로 n-1개의 원판을 이동하는 문제
// 막대 from에 쌓여 있는 n개의 원찬을 막대 tmp를 사용하여 막대 to로 옮긴다.
void hanoi_tower(int n, char from, char tmp, char to){
	if(n == 1){
    	from에서 to로 원판을 옮긴다.
    }else{
    	hanoi_tower(n-1, from, to, tmp); // to를 사용하여 from에서 tmp로 n-1개 원판을 이동
        from에 있는 한 개의 원판을 to로 옮긴다.
        hanoi_tower(n-1, tmp, from, to); // from을 사용하여 tmp에서 to로 n-1개 원판을 이동
    }
}

<프로그램 2.4.1> 하노이탑 문제 프로그램

#include <stdio.h>
void hanoi_tower(int n, char from, char tmp, char to){
	if(n == 1){
    	printf("원판 1을 %c에서 %c으로 옮긴다.\n",from, to);
    }else{
    	hanoi_tower(n-1, from, to, tmp);
        printf("원판 1을 %c에서 %c으로 옮긴다.\n",from, to);
		hanoi_tower(n-1, tmp, from, to);
    }
}

main(){
	hanoi_tower(4,'A','B','C');
}

- 반복적인 형태로 바꾸기 어려운 순환

다음 팩토리얼 예제에서 차이점

1. return n * factorial(n-1);
2. return factorial(n-1) * n;
  • 꼬리 순환(tail recursion)은 1처럼 순환 호출이 순환 함수의 맨 끝에서 이루어지는 형태의 순환, 이 경우 알고리즘은 쉽게 반복적인 현태로 변환이 가능
  • 머리 순환(head recursion)인 2나 하노이탑 문제처럼 여러 군데에서 자기자신을 호출하는 경우(multi recursion)는 쉽게 반복적인 코드로 바꿀 수 없음

Quiz

  1. 순환을 사용하는 방법에 대한 설명 중 잘못된 것은? -> 3
    (1) 순환적으로 정의된 문제에 적합하다.
    (2) 반복을 이용하는 것보다 효율적이다.
    (3) 간접적으로 시스템 스택이 사용된다.
    (4) 순환이 될 때마다 문제의 크기는 작아진다.
저작자표시 (새창열림)

'다양한 글들 > 자료구조와 알고리즘' 카테고리의 다른 글

8. 힙 정렬  (0) 2023.04.01
3. 다중 순환  (0) 2023.03.30
1. 재귀(순환)  (0) 2023.03.23
7. 퀵 정렬 (Quick Sort)  (0) 2023.03.23
6. 병합(합병) 정렬 (Merge Sort)  (0) 2023.03.23
'다양한 글들/자료구조와 알고리즘' 카테고리의 다른 글
  • 8. 힙 정렬
  • 3. 다중 순환
  • 1. 재귀(순환)
  • 7. 퀵 정렬 (Quick Sort)
smile blog
smile blog
건국대 첨단바이오공학부 & 컴퓨터공학부 BT & IT 기술로 희망을 꿈 꿉니당
  • smile blog
    스마일 블로그
    smile blog
  • 전체
    오늘
    어제
    • 분류 전체보기 (826) N
      • 일상 생각들 (3)
      • 학과에 대해 (4)
        • 첨단바이오공학부 (4)
        • 컴퓨터공학부 (0)
      • -------- 프로젝트 -------- (0)
      • [DS] 토이 프로젝트 (1)
      • [Web, Game, XR] 토이 프로젝트 (11)
      • 경진대회 (1)
      • -------- 진로 -------- (0)
      • 생물정보학자 (18)
        • 데이터 과학이란? (0)
        • 되는 방법 (8)
        • 책 추천 (2)
        • 인강 (1)
        • 대학 (2)
        • 회사 (1)
        • 학원 (2)
        • 학회 (2)
      • 디지털 헬스케어 (72)
        • 방법 (8)
        • 생각들 (10)
        • 공부법 (4)
        • 책 추천 (2)
        • 학원 (2)
        • 참고 (2)
        • 대학 (3)
        • 회사 (3)
        • 인강 (2)
        • 게임 엔진들 (1)
        • 게임 프로그래머 개론 (2)
        • 게임 프로그래머 취업 전략 가이드 (7)
        • 취업 서류 (1)
        • 애정하는 게임들 (4)
        • XR 테크니컬 아티스트 (9)
        • 영화, 애니메이션 테크니컬 디렉터 (12)
      • -------- 기초 학문 -------- (0)
      • 생명과학 이야기 (2)
        • 대학 강의 (2)
      • 화학 이야기 (0)
      • 컴퓨터과학 이야기 (0)
      • 통계학 이야기 (0)
      • 수학 이야기 (1)
        • 공학 수학 (1)
      • 영어 이야기 (1)
      • 심리학 이야기 (7)
        • 현대인과 정신건강 (7)
      • -------- 컴퓨터 언어 -------- (0)
      • Python (3)
        • 나도코딩의 파이썬 입문 (1)
        • 파이썬 관련 정보 (1)
      • SQL (0)
      • C 언어 (32)
        • 혼자 공부하는 C언어 요약 (1)
        • [책 정리] 혼자 공부하는 C언어 (31)
      • C++ (33)
        • 명품 C++ 프로그래밍 요약 (1)
        • [책 정리] 명품 C++ 프로그래밍 (27)
        • C++ STL (0)
        • 뇌를 자극하는 C++ STL (5)
      • -------- 생명과학 -------- (0)
      • 생화학 (5)
        • 대학 강의 (5)
      • 분자세포생물학 (3)
        • 대학 강의 (3)
      • 유전자치료공학 (2)
        • 대학 강의 (2)
      • 생명정보학 (6)
        • 대학 강의 (6)
      • 약리학 (2)
        • 대학 강의 (2)
      • -------- 컴퓨터과학 -------- (0)
      • 자료구조와 알고리즘 (8)
        • 자료구조와 알고리즘의 정의 (3)
        • [책 정리] C언어로 쉽게 풀어쓴 자료구조 요약 (1)
        • [인강] 자료구조와 알고리즘 (2)
        • 코딩 테스트 대비하기! (1)
      • 컴퓨터 회로 (0)
      • 컴퓨터 구조 (43)
        • 컴퓨터 구조와 운영체제 요약 (1)
        • ---------------------------------------- (0)
        • [전공 책 정리] 컴퓨터 구조 및 설계 (1)
        • Ch1. 컴퓨터 추상화 및 관련 기술 (8)
        • Ch2. 명령어 : 컴퓨터 언어 (11)
        • Ch3. 컴퓨터 연산 (8)
        • Ch4. 프로세서 (11)
        • Ch5. 메모리 계층구조 (3)
        • Ch6. 병렬 프로세서 : 클라이언트에서 클라우드까지 (0)
      • 시스템 프로그래밍 (15)
        • [책 정리] 시스템 프로그래밍 유닉스 & 리눅스 (0)
        • [인강] 리눅스 시스템 프로그래밍 (2)
        • 리눅스에서 코딩이란? (8)
        • 대학교 강의 정리 (5)
      • 운영체제 (0)
      • 컴퓨터 네트워크 (37)
        • 모두의 네트워크 요약 (1)
        • [책 정리] 모두의 네트워크 (10)
        • ---------------------------------------- (0)
        • [전공 책 정리] 컴퓨터 네트워킹 하향식 접근 8판 (1)
        • Ch1. 컴퓨터 네트워크와 인터넷 (7)
        • Ch2. 애플리케이션 계층 (7)
        • Ch3. 트랜스포트 계층 (8)
        • Ch4. 네트워크 계층 : 데이터 평면 (3)
        • Ch5. 네트워크 계층 : 제어 평면 (0)
        • Ch6. 링크 계층과 근거리 네트워크 (0)
        • Ch7. 무선 및 이동 네트워크 (0)
        • Ch8. 컴퓨터 네트워크 보안 (0)
      • 데이터베이스 (1)
      • -------- 데이터과학 -------- (0)
      • 데이터 사이언스 (8)
        • 인강 (8)
      • 데이터 분석 (2)
        • 인강 (2)
      • 머신러닝 (2)
        • 대학 수업 (2)
      • 인공지능 (11)
        • 대학교 강의 정리 (10)
        • 인공지능 관련 정보 (1)
      • -------- +a -------- (0)
      • Visual Studio Community (7)
        • 설치법 (1)
        • 단축키 (1)
        • 오류 (5)
      • Visual Studio Code (0)
      • 노션 (1)
      • 깃허브 (7)
        • 깃허브 사용법 (5)
        • 유니티, 언리얼 & 깃허브 (1)
        • 깃허브 주의사항 (1)
      • 챗GPT 활용법 (0)
      • 기타 feat. 프로그래밍 (7)
        • 프로그래머로 살아남기 (5)
        • 코딩 vs 프로그래밍 (1)
        • 애플 비전 프로 (1)
      • 메타버스 (5)
      • -------- 예술 -------- (0)
      • 음악 (1)
      • 미술 (0)
      • -------- XR -------- (0)
      • 유니티 이야기 (23)
        • 레트로의 유니티 게임 프로그래밍 에센스 요약 (4)
        • 유니티 관련 정보 (1)
        • 유니티 디버깅 (13)
        • 유니티 인강 (3)
        • 대학교 게임 프로그래밍 강의 (2)
      • 언리얼 이야기 (0)
        • 인생 언리얼 교과서 요약 (0)
      • 컴퓨터 그래픽스 (6)
        • OpenGL (6)
      • 가상현실 & 증강현실 (4)
        • 유니티 vr (4)
      • HCI 와 UI UX (7)
        • [책 정리] HCI 개론 (6)
      • -------- Design -------- (0)
      • 캐릭터 (1)
        • 모델링 (0)
        • 리깅 (1)
      • 포토샵 (3)
      • 3ds Max (7)
      • Maya (9)
        • 블로그 (1)
        • 인강 (6)
        • 대학교 (2)
      • Blender (14)
        • 책 (1)
        • 인강 (7)
        • 기타 (3)
        • 대학교 (3)
      • 아트 작업물들 (2)
      • 에셋 사이트 (1)
      • -------- 건강관리 -------- (0)
      • 건강관리 ft. 정현 (12)
        • 목 디스크 (2)
        • 눈 관리 (2)
        • 일상생활 습관 (6)
        • 일상생활 꿀팁 (2)
        • 사무직 꿀팁 (0)
      • 헬스의 정석 ft. 정현 (28)
        • 헬스와 건강 (8)
        • 헬스 구체화 정보 (6)
        • 헬스 유튜버 (1)
        • 헬스 서적 (1)
        • 도전 바디프로필! (11)
        • 헬스장 패션 (1)
      • -------- etc -------- (0)
      • 진로 관련 잡다한 글들 (34)
        • 진도율 (9)
        • 진로 관련 글들 (15)
        • 학교 강의 관련 글들 (10)
      • 인생 꿀 Tip (23)
        • 컴퓨터 초기 설정 (9)
        • 원격 데스크톱 (1)
        • 노트북 발열 (1)
        • 전자기기 (2)
        • 중고기기 팔기 (1)
        • 아이패드 필기 어플 (1)
        • 에어팟 (1)
        • 커피 (1)
        • 맥북 (1)
        • lg 그램 (1)
        • 검색엔진에서 내 티스토리 검색 (1)
        • hELLO 다크 모드 없애기 (1)
        • 인터넷 연결 문제 (1)
        • 키보드 문제 해결 (1)
      • 유튜브 (3)
      • 청춘 그리고 추억 (1)
      • 인생 계획표 (2)
        • 2024년 2학기 (1)
        • 2024년 여름방학 (0)
        • 2024년 1학기 (0)
        • 2023년 겨울방학 (1)
      • 다양한 글들 (98)
        • C++ STL (6)
        • Win32 API (24)
        • PushPush 게임 (13)
        • 컴퓨터구조 (1)
        • 자료구조와 알고리즘 (50)
        • 게임의 정의 (3)
        • 영상 회사 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • Dream
    • 코딩을 시작한 이유
    • 나를 소개합니다!
    • 블로그 공부법
    • IT & 가치 있는 일들
  • 인기 글

  • 태그

    블렌더
    생명과학
    unity
    리눅스
    알고리즘
    생물정보학
    AI
    컴퓨터구조
    심리학
    연산자
    의생명정보알고리즘
    코딩
    건국대
    함수
    배열
    의생명공학과
    데이터과학
    C언어
    컴퓨터 네트워크
    생명공학
    포인터
    유니티
    첨단바이오공학부
    명령어
    데이터사이언스
    의생명공학
    C++
    인공지능
    스택
    자료구조
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
smile blog
2. 재귀를 활용한 계산
상단으로

티스토리툴바