재귀는 많은 알고리즘 문제에서 강력한 도구로 활용된다. 특히 문자열 처리 문제에서 재귀를 사용하면 간결하고 효율적인 해결책을 제시할 수 있다. 이번 포스트에서는 백준의 문제 25501번: 재귀의 귀재를 통해 재귀 함수를 이용한 팰린드롬 판별과 재귀 호출 횟수 세는 방법을 알아보겠다.
문제 : https://www.acmicpc.net/problem/25501
문제 설명
백준 온라인 저지의 25501번: 재귀의 귀재 문제는 주어진 문자열이 팰린드롬인지 여부를 판단하고, 이를 판별하는 과정에서 재귀 함수가 몇 번 호출되는지를 세는 문제이다. 팰린드롬이란, 앞에서부터 읽었을 때와 뒤에서부터 읽었을 때가 같은 문자열을 말한다. 예를 들어, “ABBA"나 “ABABA"는 팰린드롬이지만, “ABCA"는 팰린드롬이 아니다.
문제는 다음과 같은 방식으로 진행된다:
- 문자열 S가 주어진다.
- 재귀 함수를 사용하여 S가 팰린드롬인지 판별한다.
- 재귀 함수가 호출된 횟수를 세어 출력한다.
입력으로는 테스트케이스의 수 T와 그에 따른 T개의 문자열 S가 주어지며, 각 문자열에 대해 팰린드롬 여부와 재귀 호출 횟수를 출력해야 한다.
접근 방식
이 문제를 해결하기 위해 재귀 함수를 사용하여 문자열의 양 끝 문자부터 비교해 나가는 방식을 채택하였다. 재귀 함수는 문자열의 좌측 인덱스 l과 우측 인덱스 r을 받아 다음과 같이 동작한다:
- 기본 사례(Base Case):
- 만약 l이 r 이상이 되면, 모든 문자가 일치했으므로 팰린드롬이다.
- 재귀 단계(Recursive Step):
- S[l]과 S[r]이 다르면, 더 이상 확인할 필요 없이 팰린드롬이 아니다.
- S[l]과 S[r]이 같다면, l을 증가시키고 r을 감소시켜 다음 문자들을 비교하기 위해 재귀 호출을 한다.
또한, 재귀 호출의 횟수를 세기 위해 전역 변수나 참조 변수를 활용하여 호출될 때마다 카운트를 증가시킨다.
이 접근 방식은 문자열의 길이에 비례하는 시간 복잡도 O(N)을 가지며, N은 문자열의 길이이다. 이는 문자열의 절반만을 확인하면 되기 때문에 효율적이다.
C++ 코드와 설명
| |
코드의 동작 단계별 설명
입력 및 초기화:
ios::sync_with_stdio(false);와cin.tie(NULL);을 통해 입출력 속도를 최적화한다.- 테스트케이스의 수 T를 입력받는다.
테스트케이스 처리:
- 각 테스트케이스마다 문자열 S를 입력받는다.
- 재귀 호출 횟수를 세기 위해
cnt를 0으로 초기화한다. isPalindrome함수를 호출하여 팰린드롬 여부를 판단하고, 그 결과와 재귀 호출 횟수를 출력한다.
재귀 함수
recursion:- 함수가 호출될 때마다
cnt를 1 증가시킨다. - 현재 좌측 인덱스 l이 우측 인덱스 r보다 크거나 같으면 모든 문자가 일치한 것이므로 1을 반환한다.
- S[l]과 S[r]이 다르면 팰린드롬이 아니므로 0을 반환한다.
- S[l]과 S[r]이 같으면, l을 증가시키고 r을 감소시켜 다음 문자들을 비교하기 위해 재귀 호출을 한다.
- 함수가 호출될 때마다
C++ without library 코드와 설명
| |
코드의 동작 단계별 설명
입력 및 초기화:
scanf를 사용하여 테스트케이스의 수 T를 입력받는다.
테스트케이스 처리:
- 각 테스트케이스마다 문자열 S를 입력받는다. 문자열의 최대 길이가 1000이므로
char S[1001];로 선언한다. - 재귀 호출 횟수를 세기 위해
cnt를 0으로 초기화한다. isPalindrome함수를 호출하여 팰린드롬 여부를 판단하고, 그 결과와 재귀 호출 횟수를printf를 통해 출력한다.
- 각 테스트케이스마다 문자열 S를 입력받는다. 문자열의 최대 길이가 1000이므로
재귀 함수
recursion:- 함수가 호출될 때마다
cnt를 1 증가시킨다. - 현재 좌측 인덱스 l이 우측 인덱스 r보다 크거나 같으면 모든 문자가 일치한 것이므로 1을 반환한다.
- S[l]과 S[r]이 다르면 팰린드롬이 아니므로 0을 반환한다.
- S[l]과 S[r]이 같으면, l을 증가시키고 r을 감소시켜 다음 문자들을 비교하기 위해 재귀 호출을 한다.
- 함수가 호출될 때마다
Python 코드와 설명
| |
코드의 동작 단계별 설명
입력 및 초기화:
sys.setrecursionlimit(10000)을 통해 재귀 한도를 늘려 긴 문자열도 처리할 수 있도록 한다.- 표준 입력을 읽어 모든 데이터를 한 번에 받아 처리한다.
테스트케이스 처리:
- 첫 번째 입력 값 T를 테스트케이스의 수로 설정한다.
- 각 테스트케이스마다 문자열 S를 입력받고, 재귀 호출 횟수를 세기 위해
cnt를 0으로 초기화한다. isPalindrome함수를 호출하여 팰린드롬 여부를 판단하고, 그 결과와 재귀 호출 횟수를 출력한다.
재귀 함수
recursion:- 함수가 호출될 때마다
cnt를 1 증가시킨다. - 현재 좌측 인덱스 l이 우측 인덱스 r보다 크거나 같으면 모든 문자가 일치한 것이므로 1을 반환한다.
- S[l]과 S[r]이 다르면 팰린드롬이 아니므로 0을 반환한다.
- S[l]과 S[r]이 같으면, l을 증가시키고 r을 감소시켜 다음 문자들을 비교하기 위해 재귀 호출을 한다.
- 함수가 호출될 때마다
결론
이번 문제를 통해 재귀 함수를 사용하여 문자열이 팰린드롬인지 여부를 판단하고, 재귀 호출의 횟수를 효율적으로 세는 방법을 배웠다. 재귀는 코드의 가독성을 높이고, 복잡한 문제를 단순하게 해결할 수 있는 강력한 도구이다. 하지만 재귀 호출의 깊이가 깊어질 경우 스택 오버플로우가 발생할 수 있으므로, 필요한 경우 재귀 한도를 조정하거나 반복문으로 대체하는 방안도 고려해야 한다. 또한, 재귀 호출 횟수를 세는 방식은 전역 변수를 사용하거나 함수의 인자로 참조 변수를 전달하는 방법으로 구현할 수 있으며, 이는 문제의 요구사항에 따라 적절히 선택해야 한다. 이번 문제를 통해 재귀의 활용과 효율적인 구현 방법에 대해 깊이 이해할 수 있었다.
![Featured image of post [Algorithm] C++/Python 백준 25501번 : 재귀의 귀재](/post/algorithm/2024-10-25-boj-25501/tmp_wordcloud_hu_b5c1f261dcb322fe.png)
![[Algorithm] C++/Python 백준 14924번 : 폰 노이만과 파리](/post/algorithm/2024-10-25-boj-14924/tmp_wordcloud_hu_ff97e78975952361.png)
![[Algorithm] C++/Python 백준 16189번 : Repetitive Palindrome](/post/algorithm/2024-10-25-boj-16189/tmp_wordcloud_hu_a986a5920bee59de.png)
![[Algorithm] C++/Python 백준 25501번 : 재귀의 귀재](/post/algorithm/2024-10-25-boj-25501/tmp_wordcloud_hu_772ee0523ffc09ab.png)
![[Algorithm] C++/Python 백준 2975번 : Transactions 다국어](/post/algorithm/2024-10-25-boj-2975/tmp_wordcloud_hu_fc7155c30c95b305.png)
![[Algorithm] C++/Python 백준 5544번 : 리그 순위 계산](/post/algorithm/2024-10-25-boj-5544/tmp_wordcloud_hu_f6781c2088f36e2c.png)
![[Algorithm] C++/Python 백준 5342번 : Billing 다국어](/post/algorithm/2024-10-17-boj-5342/tmp_wordcloud_hu_823a5d86092c575a.png)
![[Algorithm] C++/Python 백준 2711번 : 오타맨 고창영](/post/algorithm/2024-10-17-boj-2711/tmp_wordcloud_hu_c570984b236d8e2b.png)
![[Algorithm] cpp 백준 13576번: Prefix와 Suffix](/post/algorithm/2025-08-14-boj-13576-prefix-and-suffix-cpp-solution/wordcloud_hu_72d54380bd8dc598.png)
![[Algorithm] C++/Python 백준 10266번 : 시계 사진들](/post/algorithm/2024-12-31-boj-10266/index_hu_a0db04a13ee35bc1.png)
![[Algorithm] cpp 백준 10538번: 빅 픽쳐 - 2D 롤링 해시로 O(HW) 매칭](/post/algorithm/2025-08-14-boj-10538-big-picture-cpp-solution/wordcloud_hu_3fef2b22c9e53634.png)