도서관에서 일어나는 다양한 작업을 기록하고 조회하는 도서관 관리 시스템을 개발한다고 가정해 보겠습니다. 이 시스템에는 다음과 같은 세 가지 명령을 구현해야 합니다.
- 명령 1: x번 선반에 y페이지 분량의 책 한 권을 추가합니다.
- 명령 2: x번 선반에 있는 y번째 책의 페이지 수를 출력합니다.
- 명령 3: x번 선반에 보관된 책의 총 개수를 출력합니다.
명령은 {명령 유형, x, y} 형식의 2차원 배열로 전달되며, y 값이 필요하지 않은 경우 기본값으로 0이 사용됩니다. 프로그램은 각 명령의 실행 결과를 순서대로 출력해야 합니다.
문제 예시
선반의 개수가 4개, 쿼리가 4개이고 입력 배열이 다음과 같다고 해봅시다.
input_arr = {{1, 3, 23}, {1, 4, 128}, {2, 3, 0}, {3, 4, 0}};이때 프로그램의 출력은 다음과 같습니다.
23 1
실행 과정 설명
- 명령 1 — 3번 선반에 23페이지짜리 책을 삽입합니다.
- 명령 2 — 4번 선반에 128페이지짜리 책을 삽입합니다.
- 명령 3 — 3번 선반의 0번째 책의 페이지 수를 출력합니다. → 23
- 명령 4 — 4번 선반에 있는 책의 개수를 출력합니다. → 1
해결 접근 방법
이 문제는 각 선반이 서로 다른 개수의 책을 가질 수 있으므로, 동적 메모리 할당(malloc, realloc)을 이용한 가변 길이 배열로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.
b: 크기가 s인 정수 배열로, 각 선반에 있는 책의 개수를 저장합니다.p: 크기가 s인 포인터 배열로, 각 선반의 책 페이지 정보를 담는 동적 배열을 가리킵니다.- 초기화 단계에서 모든
b[i]를 0으로 설정하고,p[i]마다 새로운 배열을 할당합니다. - 쿼리를 하나씩 처리하며 명령 유형(
qtype)에 따라 동작을 수행합니다.- qtype == 1 (삽입) :
b[x]를 1 증가시키고,realloc()으로p[x]의 크기를 늘린 뒤 마지막 위치에 페이지 수 y를 저장합니다. - qtype == 2 (조회) :
p[x][y]값을 출력합니다. - 그 외 (개수 확인) :
b[x]값을 출력합니다.
- qtype == 1 (삽입) :
- 모든 작업이 끝나면
free()를 사용하여 할당된 메모리를 반드시 해제하여 메모리 누수를 방지합니다.
C 언어 구현 코드
다음은 위 알고리즘을 실제로 구현한 C 프로그램입니다.
#include <stdio.h>
#include <stdlib.h>
void solve(int s, int q, int q_array[][3])
{
int* b;
int** p;
b = (int*)malloc(sizeof(int)*s);
p = (int**)malloc(sizeof(int*)*s);
for(int i = 0; i < s; i++)
{
b[i] = 0;
p[i] = (int*)malloc(sizeof(int));
}
int loopCount;
for(loopCount = 0; loopCount < q; loopCount++)
{
int qtype;
qtype = q_array[loopCount][0];
if (qtype == 1)
{
int x, y;
x = q_array[loopCount][1];
y = q_array[loopCount][2];
b[x] += 1;
p[x] = realloc(p[x], b[x]*sizeof(int));
p[x][b[x] - 1] = y;
}
else if (qtype == 2)
{
int x, y;
x = q_array[loopCount][1];
y = q_array[loopCount][2];
printf("%d\n", p[x][y]);
}
else
{
int x;
x = q_array[loopCount][1];
printf("%d\n", b[x]);
}
}
if (b)
free(b);
for (int i = 0; i < s; i++)
if (p[i])
free(p[i]);
if (p)
free(p);
}
int main() {
int input_arr[][3] = {{1, 3, 23}, {1, 4, 128}, {2, 3, 0}, {3, 4, 0}};
solve(4, 4, input_arr);
}입력
int input_arr[][3] = {{1, 3, 23}, {1, 4, 128}, {2, 3, 0}, {3, 4, 0}};
solve(4, 4, input_arr);출력
23 1
정리
이 예제는 C 언어에서 malloc(), realloc(), free()를 조합하여 고정된 크기의 2차원 배열 대신 실행 중에 크기가 늘어나는 가변 길이 배열을 만드는 방법을 잘 보여줍니다. 특히 선반마다 서로 다른 개수의 데이터를 저장해야 하는 상황에서 메모리를 효율적으로 사용할 수 있으며, 사용이 끝난 메모리를 반드시 해제하는 습관이 중요하다는 점도 함께 기억해 두면 좋습니다.