Company
교육 철학

LV06 cstring, 재귀함수 호출의 깊이와 너비

C++ C-string과 고급 재귀함수

C-string 라이브러리

C-string의 개념과 중요성

문장을 비교 할 때 기존의 방법은 반복문을 사용해 두 배열의 글자가 다른지 확인해주는 작업을 거쳐야 했었다. 이제 여러 문자열을 처리 하기 위해서 직접 로직을 작성하지 않고 이미 만들어진 로직을 가져다 사용할수 있다.

기존 문자열 비교 방법 (수동)

#include <iostream> using namespace std; int flag = 0; for (size_t i = 0; i < 10; i++) { if (nameA[i] != nameB[i]) { flag = 1; break; } } if (flag == 0) { //같다 } else { //다르다 }
C++
복사
기존 방법의 단점:
매번 반복문을 작성해야 함
문자열 길이를 미리 알아야 함
코드가 길고 복잡함
실수할 가능성이 높음

C-string 라이브러리 사용

이제는 cstring 라이브러리를 사용해서 두 문장이 같은지 비교해주면 된다.
#include <iostream> #include <cstring> // C-string 라이브러리 포함 using namespace std; int main() { char strA[256] = "Hello"; char strB[256] = "Hello"; if (strcmp(strA, strB) == 0) { cout << "문자열이 같습니다." << endl; } else { cout << "문자열이 다릅니다." << endl; } return 0; }
C++
복사

주요 C-string 함수들

1. 문자열 길이 구하는 함수
// 문자열 길이 구하는 함수 int len = strlen(nameA);
C++
복사
2. 문자열 복사 함수 (복사할 위치, 복사할 소스)
// 문자열 복사 함수 (복사할 위치, 복사할 소스) strcpy_s(nameC, nameA);
C++
복사
주요 C-string 함수 정리:
함수
기능
사용법
strlen(str)
문자열 길이 반환
int len = strlen(str);
strcmp(str1, str2)
문자열 비교
if (strcmp(str1, str2) == 0)
strcpy(dest, src)
문자열 복사
strcpy(dest, src);
strcpy_s(dest, size, src)
안전한 문자열 복사
strcpy_s(dest, 256, src);
strcat(dest, src)
문자열 연결
strcat(dest, src);
strcat_s(dest, size, src)
안전한 문자열 연결
strcat_s(dest, 256, src);
strcmp 함수 반환값:
0: 두 문자열이 같음
양수: 첫 번째 문자열이 사전순으로 뒤에 옴
음수: 첫 번째 문자열이 사전순으로 앞에 옴

재귀함수의 깊이와 너비

재귀함수 호출 빈도(깊이)를 조절하는 방법

우리는 이전에 재귀함수의 호출 빈도(깊이)를 조절하는 방법을 배웠었다.
#include <iostream> using namespace std; void BBQ(int level) { if (level == 3) // 종료 조건 { return; } BBQ(level + 1); // 재귀 호출 } int main() { BBQ(0); // level 0부터 시작 return 0; }
C++
복사
재귀 호출 과정:
Main → BBQ(0) → BBQ(1) → BBQ(2) → BBQ(3) → return
Plain Text
복사
레벨별 스택 프레임:
Level 0: BBQ(0) 호출, level=0
Level 1: BBQ(1) 호출, level=1
Level 2: BBQ(2) 호출, level=2
Level 3: BBQ(3) 호출, level=3, return 실행

재귀함수 실행 과정 시각화

이번 재귀함수 함번이 아닌 두번을 호출한다면 어떻게 되는지 저장보자

트리 구조 재귀 호출

#include <iostream> using namespace std; void BBQ(int level) { if (level == 2) // 깊이 2에서 종료 { return; } BBQ(level + 1); // 첫 번째 재귀 호출 BBQ(level + 1); // 두 번째 재귀 호출 cout << "BBQ" << endl; //트리 형태로는 다음과 같이 //for문으로도 표현 가능하다 //for (size_t i = 0; i < 2; i++) //{ // BBQ(level + 1); //} } int main() { BBQ(0); return 0; }
C++
복사

트리 구조 호출 과정 시각화

시작 BBQ(0) / \ BBQ(1) BBQ(1) / \ / \ BBQ(2) BBQ(2) BBQ(2) BBQ(2) | | | | return return return return
Plain Text
복사
호출 순서와 실행 흐름:
1.
BBQ(0) 시작
2.
첫 번째 BBQ(1) 호출
3.
첫 번째 BBQ(2) 호출 → return
4.
두 번째 BBQ(2) 호출 → return
5.
첫 번째 BBQ(1) 완료, "BBQ" 출력
6.
두 번째 BBQ(1) 호출
7.
세 번째 BBQ(2) 호출 → return
8.
네 번째 BBQ(2) 호출 → return
9.
두 번째 BBQ(1) 완료, "BBQ" 출력
10.
BBQ(0) 완료, "BBQ" 출력
최종 출력: "BBQ" 3번 출력
재귀 함수를 여러번 호출하게 되면 위와같은 형태로 출력되게 된다.
이를 잘 활용해서 여러가지 문제를 풀어보도록 하자.

만약 재귀함수 호출이 3개라면?

3개의 재귀 호출

#include <iostream> using namespace std; void BBQ(int level) { if (level == 2) { return; } //BBQ(level + 1); //BBQ(level + 1); //BBQ(level + 1); for (size_t i = 0; i < 3; i++) { BBQ(level + 1); } cout << "BBQ" << endl; } int main() { BBQ(0); return 0; }
C++
복사

3개 호출의 트리 구조

BBQ(0) / | \ BBQ(1) BBQ(1) BBQ(1) / | \ / | \ / | \ BBQ(2)BBQ(2)BBQ(2)BBQ(2)BBQ(2)BBQ(2)BBQ(2)BBQ(2)BBQ(2)
Plain Text
복사
호출 횟수 계산:
Level 0: 1회 (BBQ(0))
Level 1: 3회 (BBQ(0)에서 3번 호출)
Level 2: 9회 (각 BBQ(1)에서 3번씩 호출)
총 호출 횟수: 1 + 3 + 9 = 13회
"BBQ" 출력 횟수: 4회 (3개의 BBQ(1) + 1개의 BBQ(0))

재귀함수 활용 예제

1. 팩토리얼 계산

int factorial(int n) { if (n <= 1) { return 1; } return n * factorial(n - 1); } // factorial(5) = 5 * 4 * 3 * 2 * 1 = 120
C++
복사

2. 피보나치 수열 (이진 트리 재귀)

int fibonacci(int n) { if (n <= 1) { return n; } return fibonacci(n - 1) + fibonacci(n - 2); // 2개의 재귀 호출 } // fibonacci(4) 호출 트리: // fib(4) // / \ // fib(3) fib(2) // / \ / \ // fib(2) fib(1) fib(1) fib(0) // / \ //fib(1) fib(0)
C++
복사

3. 하노이의 탑

void hanoi(int n, char from, char to, char aux) { if (n == 1) { cout << from << "에서 " << to << "로 이동" << endl; return; } hanoi(n - 1, from, aux, to); // 첫 번째 재귀 cout << from << "에서 " << to << "로 이동" << endl; hanoi(n - 1, aux, to, from); // 두 번째 재귀 }
C++
복사

재귀함수 최적화와 주의사항

메모이제이션 (Memoization)

#include <iostream> using namespace std; int memo[100] = {0}; // 메모 배열 int fibonacci_memo(int n) { if (n <= 1) return n; if (memo[n] != 0) // 이미 계산된 값이 있으면 { return memo[n]; } memo[n] = fibonacci_memo(n - 1) + fibonacci_memo(n - 2); return memo[n]; }
C++
복사

실무에서의 재귀 활용

파일 시스템 탐색

void listDirectory(const string& path, int depth = 0) { // 들여쓰기 출력 for (int i = 0; i < depth; i++) cout << " "; cout << path << endl; // 하위 디렉토리들에 대해 재귀 호출 // for (각 하위 디렉토리) // { // listDirectory(하위디렉토리, depth + 1); // } }
C++
복사

JSON 파싱

void parseJSON(JSONNode node, int depth = 0) { if (node.isObject()) { for (auto& child : node.children) { parseJSON(child, depth + 1); // 재귀적으로 파싱 } } }
C++
복사
C-string 라이브러리는 문자열 처리를 간편하게 해주며, 다중 재귀는 복잡한 구조를 표현하는 데 유용합니다. 하지만 성능과 메모리 사용량을 항상 고려해야 하며, 필요에 따라 메모이제이션이나 반복문으로 최적화하는 것이 중요합니다.

“강의는 많은데, 왜 나는 아직도 코드를 못 짤까?”

혼자 공부하다 보면 누구나 이런 고민을 하게 됩니다.
강의는 다 들었지만 막상 손이 안 움직이고,
복습을 하려 해도 무엇을 다시 봐야 할지 모르겠고,
질문할 곳도 없고,
유튜브는 결국 정답을 따라 치는 것밖에 안 되는 것 같고.
문제는 ‘연습’이 빠졌기 때문입니다.
단순히 강의를 듣는 것만으로는 실력이 늘지 않습니다.
실제 문제를 풀고, 고민하고, 직접 구현해보는 시간이 반드시 필요합니다.

그래서, 얌얌코딩 코칭은 다릅니다.

그냥 가르치지 않습니다.
스스로 설계하고, 코딩할 수 있게 만듭니다.
얌얌코딩 코칭에서는 단순한 예제가 아닌,
스스로 문제를 분석하고 구현해야 하는 연습문제를 제공합니다.
이 연습문제들은 다음과 같은 역량을 키우기 위해 설계되어 있습니다:
문제를 스스로 쪼개고 설계하는 힘
다양한 조건을 만족시키는 실제 구현 능력
기능 단위가 아닌, 프로그램 단위로 사고하는 습관
마침내 자신의 힘으로 코드를 끝까지 작성하는 경험

지금 필요한 건 더 많은 강의가 아닙니다.

코드를 스스로 완성해 나가는 훈련,
그것이 지금 실력을 끌어올릴 가장 현실적인 방법입니다.
자세한 안내 보기: 프리미엄 코칭 안내 바로가기
또는 카카오톡 상담방: 얌얌코딩 상담방