프로그래머스 입문 120913 잘라서 배열로 저장하기
문제
문자열을 앞에서부터 n글자씩 잘라 배열로 반환하시오.
my_str |
n |
result |
|---|---|---|
| “abc1Addfggg4556b” (16) | 6 | [“abc1Ad”, “dfggg4”, “556b”] |
| “abcdef123” (9) | 3 | [“abc”, “def”, “123”] |
| “abcde” (5) | 2 | [“ab”, “cd”, “e”] |
괄호 안의 숫자는 출처에는 없는 값으로, 문자열의 길이를 임의로 적은 것이다.
풀이
고정 길이 반복문으로 문자열 나누기
#include <stdlib.h>
#include <string.h>
char** solution(const char* my_str, int n)
{
int len = strlen(my_str);
int chunk_size = n;
int chunk_count = (len + chunk_size - 1) / chunk_size;
char** result = malloc(sizeof(char*) * chunk_count);
for (int i = 0; i < chunk_count; i++)
{
result[i] = malloc(sizeof(char) * (chunk_size + 1));
for (int j = 0; j < chunk_size; j++)
{
result[i][j] = my_str[i * chunk_size + j];
}
result[i][chunk_size] = '\0';
}
return result;
}
문제에서 주어진 매개변수 n의 의미를 명확하게 하려고 chunk_size에 담아 사용했다.
문자열의 길이를 chunk_size로 나누면 필요한 청크 수를 구할 수 있다.
다만 C의 정수 나눗셈은 소수점 이하를 버리므로, 나머지 문자열이 있을 때 마지막 청크가 계산에서 빠질 수 있다.
문제에서는 자르고 남은 문자열도 배열에 포함해야 하므로 나머지가 있다면 청크 하나를 더 확보해야 한다.
이를 올림 나눗셈으로 처리한 코드가 (len + chunk_size - 1) / chunk_size이다.
이 코드에서는 마지막 청크의 길이가 chunk_size보다 작을 수 있지만, result[i]는 항상 chunk_size + 1만큼 넉넉하게 할당한다.
다음 풀이에서는 마지막 청크의 실제 길이를 계산해 필요한 만큼만 공간을 잡고, 문자는 memcpy로 복사한다.
memcpy로 복사
#include <stdlib.h>
#include <string.h>
char** solution(const char* my_str, int n)
{
int len = strlen(my_str);
int chunk_size = n;
int chunk_count = (len + chunk_size - 1) / chunk_size;
char** result = malloc(sizeof(char*) * chunk_count);
for (int i = 0; i < chunk_count; i++)
{
int start_index = i * chunk_size;
int remaining_len = len - start_index;
int copy_len = remaining_len < chunk_size ? remaining_len : chunk_size;
result[i] = malloc(sizeof(char) * (copy_len + 1));
memcpy(result[i], my_str + start_index, copy_len);
result[i][copy_len] = '\0';
}
return result;
}
전체적인 흐름은 이전 풀이와 같지만, 마지막 청크는 실제 복사할 길이에 맞춰 공간을 동적 할당한다.
그리고 문자를 직접 하나씩 대입하는 대신 memcpy로 지정한 길이만큼 복사한다.
마지막 청크는 chunk_size보다 짧을 수 있으므로, 먼저 remaining_len으로 현재 위치부터 남아 있는 문자열 길이를 구한다.
전체 문자열 길이에서 각 청크의 시작 위치인 start_index를 빼면 남은 문자 수를 알 수 있다.
마지막 청크가 아니라면 remaining_len은 언제나 chunk_size보다 크다.
그래서 마지막 청크가 chunk_size보다 짧을 때만 copy_len에 remaining_len이 선택된다.
이렇게 계산한 copy_len에 널 문자를 위한 공간 하나를 더해 result[i]를 동적 할당한다.
그 뒤 my_str + start_index에서 시작해 copy_len만큼 memcpy로 복사하고, 마지막 위치에 '\0'을 넣어 문자열을 완성한다.