프로그래머스 입문 120888 중복된 문자 제거
문제
영문 대소문자와 공백으로 이루어진 문자열이 매개변수로 주어진다.
문자열에서 중복된 문자를 제거한 문자열을 반환하시오.
중복된 문자가 있을 경우, 가장 먼저 등장한 문자만 남긴다.
| my_string | result |
|---|---|
| “people” | “peol” |
| “We are the world” | “We arthwold” |
풀이
문자별 등장 여부 배열로 중복 제거하기
#include <stdlib.h>
#include <string.h>
char* solution(const char* my_string)
{
int len = strlen(my_string);
int result_len = 0;
unsigned char seen[128] = { 0 };
char* result = malloc(len + 1);
for (int i = 0; i < len; i++)
{
unsigned char letter = my_string[i];
if (!seen[letter])
{
seen[letter] = 1;
result[result_len++] = my_string[i];
}
}
result[result_len] = '\0';
return result;
}
문자의 ASCII 코드 값을 seen 배열의 인덱스로 사용한다.
10진수 ASCII 코드에서 공백 문자는 32이고, 대문자는 65부터 90까지, 소문자는 97부터 122까지이다.
문자열을 구성하는 문자의 종류에 맞춰 배열 크기를 더 작게 잡으려면 공백, 대문자, 소문자를 연속된 인덱스 범위로 매핑하는 과정이 필요하다.
이 풀이에서는 배열 크기를 128로 잡아 ASCII 코드 값을 그대로 인덱스로 사용했다.
처음 등장한 문자는 seen 값이 0이므로 해당 인덱스에 1을 기록하고 result에 추가한다.
이미 등장한 문자는 seen 값이 1이므로 다시 추가하지 않는다.
이전 문자와 비교해 중복 제거하기
#include <stdlib.h>
#include <string.h>
char* solution(const char* my_string)
{
int len = strlen(my_string);
int result_len = 0;
char* result = malloc(sizeof(char) * (len + 1));
for (int i = 0; i < len; i++)
{
int is_duplicated = 0;
for (int j = 0; j < i; j++)
{
if (my_string[i] == my_string[j])
{
is_duplicated = 1;
break;
}
}
if (!is_duplicated)
{
result[result_len++] = my_string[i];
}
}
result[result_len] = '\0';
return result;
}
현재 문자가 앞에서 이미 등장했는지 확인한다.
이 문제에서는 같은 문자가 여러 번 나오더라도 가장 먼저 등장한 문자만 결과에 남겨야 한다.
따라서 현재 문자를 앞쪽 문자들과 차례대로 비교한다.
같은 문자를 찾으면 중복된 문자이므로 is_duplicated를 1로 바꾸고 안쪽 반복문을 종료한다.
is_duplicated가 0인 문자만 result에 추가하므로 처음 등장한 문자만 남는다.