정리/C
[c] 재귀
멘멘
2023. 5. 7. 23:29
함수의 재귀적 호출의 이해
재귀함수 예시
void Recursive(int num)
{
if(num<=0)
return;
printf("Recursive call! %d\n",num);
Recursive(num-1);
}
int main(void){
Recursive(3);
}
재귀 활용
#include <stdio.h>
int Fibo(int n){
printf("func call param %d\n",n);
if (n==1)
return 0;
else if (n==2)
return 1;
else
return Fibo(n-1)+Fibo(n-2);
}
inr main(void){
Fibo(7);
return 0;
}
피보나치 수열 예시
하노이 타워
하노이 타워 문제 해결
- 작은 원반 n-1개를 a에서 b로 이동
- 큰 원반 1개를 a에서 c로 이동
- 작은 원반 n-1개를 b에서 c로 이동
이를 코드로 옮기면 다음과 같다.
#include <stdio.h>
void Hanoi(int num, char from, char by, char to){
if(num==1)
{
printf("원반 1을 %c에서 %c로 이동\n",from,to);
}
else
{
Hanoi(num-1,from, to, by);
printf("원반 %d을 %c에서 %c로 이동\n",num,from,to);
Hanoi(num-1,by,from,to);
}
}
int main(void){
Hanoi(3,'a','b','c');
return 0;
}
#백준 25501
문제에서 예시로 준 재귀함수 양식을 참고했습니다.
num으로 입력받을 횟수를 받고 while문을 통해 개수만큼 list에 문자들을 입력받았습니다.
입력받은 문자열을 함수에 넣은 반환값과 함수 실행횟수를 저장한 전역변수 play룰 반환해주었습니다.
#include <stdio.h>
#include <string.h>
int play = 0;
int recursion(const char *s, int l, int r){
play++;
if(l >= r) return 1;
else if(s[l] != s[r]) return 0;
else return recursion(s, l+1, r-1);
}
int isPalindrome(const char *s){
return recursion(s, 0, strlen(s)-1);
}
int main(){
int num;
scanf("%d",&num);
char list[1001] ={0};
while(num--){
play = 0;
scanf("%s",list);
int p = isPalindrome(list);
printf("%d ",p); // 1
printf("%d\n",play);
}
}
#백준 2747
위 예시를 응용해서 작성해보았는데 답은 맞았지만 시간 초과가 발생했다.
아마 재귀함수 특성상 반복문보다 시간이 더 오래 소요되어서 그런듯한데...
비슷한 질문을 한 글들의 답변을 확인해보니 동적계획법을 사용하라는 의견이 있는데...맞는지 잘 모르겠다
우선 답은 맞았으니 따로 여쭤보아야지...
#include <stdio.h>
int Fibo(int n){
if (n==0)
return 0;
else if (n==1)
return 1;
else
return Fibo(n-1)+Fibo(n-2);
}
int main(void){
int num;
scanf("%d",&num);
printf("%d",Fibo(num));
return 0;
}
#백준 11729
정답이 나왔다고 하기에도 민망한 코드...
위 예시의 식을 응용했다. 다만 실행횟수인 cnt를 하노이 함수 자체에서 새면 실행 횟수를 먼저 출력할 시 전역변수값이 0인채로 출력되기 때문에... 어떻게 처리할까 고민하다가 출력을 안하는 하노이 함수를 하나 더 만들어서 cnt만 새주는 용으로(...) 따로 출력해주었다. 뭔가 더 다른 방법이 있을 것 같지만... 생각나는 방법이 없었다......(^^;)
#include <stdio.h>
int cnt = 0;
void Hanoi(int num, int from, int by, int to){
cnt++;
if(num==1)
{
printf("%d %d\n",from,to);
}
else
{
Hanoi(num-1,from, to, by);
printf("%d %d\n",from,to);
Hanoi(num-1,by,from,to);
}
}
void Hanoi_cnt(int num, int from, int by, int to){
cnt++;
if(num==1)
{
}
else
{
Hanoi_cnt(num-1,from, to, by);
Hanoi_cnt(num-1,by,from,to);
}
}
int main(void){
int play = 0;
scanf("%d",&play);
Hanoi_cnt(play,1,2,3);
printf("%d\n",cnt);
Hanoi(play,1,2,3);
return 0;
}