🆀 문제
알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬
- 길이가 짧은 것부터
- 길이가 같으면 사전 순으로
단, 중복된 단어는 하나만 남기고 제거
🅰 나의 풀이
이 문제도 시간 제한이 걸려 있어서 Quick sort로 풀었고 이번에는 stdlib에 있는 `qsort` 함수를 사용했다.
int main() {
int n;
scanf("%d\n", &n);
char** arr = malloc(sizeof(char*) * n);
char buffer[51];
for (int i=0; i<n; i++){
scanf("%s", buffer);
arr[i] = malloc(strlen(buffer) +1);
strcpy(arr[i], buffer);
}
qsort(arr, n, sizeof(arr), compare);
for (int i=0; i<n-1; i++){
if (strcmp(arr[i], arr[i+1])!=0)
printf("%s\n", arr[i]);
free(arr[i]);
}
printf("%s\n", arr[n-1]);
free(arr);
return 0;
}
int compare(const void *a, const void *b) {
if ((strlen(*(const char**) a) - strlen(*(const char**)b))==0)
return strcmp(*(const char**) a, *(const char**) b);
return strlen(*(const char**) a) - strlen(*(const char**)b);
}
풀면서 계속 막혔던
이유 1.
: `fgets(buffer, 51, stdin)`을 사용
`fgets( )` 함수는 개행문자를 포함하여 입력 받기 때문에 개행문자 제거가 필수적이다!
공백을 포함한 입력을 받거나 파일에서 줄 단위 읽어오기가 필요할 때 유용하다.
<프로그래밍 기초>와 <자료구조> 수업 때도 계속 어려워하던 문자열 입력 받기...ㅠ
https://wifiaircat.tistory.com/23
[C] 📥 입출력 함수
🤍 C 언어의 함수 : printf, scanf, puts, getchar, gets, fgets, fputs, fscanf, fprintf, fread, fwrite, sprintf, sscanf, getc, putc, fgetc, fputc 함수용도특징사용 예시주요 차이점printf포맷된 출력포맷 문자열
wifiaircat.tistory.com
이유 2.
: `strlen(*(const char**)a))` 에서 포인터 이해 부족
- a는 `const void*`이므로 먼저 `(const char**)a` 문자열 포인터로 캐스팅해야 함.
- 그걸 `*`로 역참조하면 `char*`가 돼서 진짜 문자열을 얻을 수 있음.
- 이후 `strlen( )`으로 길이 재기
`arr[i]`는 `char*` 하나(문자열 가리키는 포인터)
`qsort( )`는 `arr[i]`의 주소를 `compare( )` 함수에 넘겨줌
`compare( )`에 들어오는 a, b는 `(void*)`라서 실제로는 `char**`(char* 의 주소)
이유 3.
: 인덱스에서 segmentation fault
정렬 후 프린트할 때 중복을 제거하는 코드에서 i와 i+1을 비교하려니까 segmentation fault가 계속 났었다.
가장 앞이나 뒤에서 예외 처리가 필요했다. 나는 뒤에서 하나의 요소를 따로 프린트했다.
항상 풀고 나면 별 것 아닌 것 같은데 풀 때는 뭐가 그렇게 어렵게 느껴지는지...ㅠ
🆂 다른 풀이
char arr[20000][51] = { 0 };
for (int i = 0; i < n; i++)
scanf("%s", arr[i]);
단어 개수 2만 개, 단어 길이 50의 제한을 적극적으로 사용할 수 있다.
동적 할당을 안 하니까 코드가 굉장히 깔끔하고 쉬워지긴 한다.
for (int i = 0; i < n; i++) {
if (strcmp(arr[i], arr[i + 1]) != 0 || i == n - 1)
printf("%s\n", arr[i]);
}
정렬 후 프린트할 때 중복을 제거하는 코드에서 i와 i+1을 비교하려다 보니까 segmentation fault가 계속 났었다.
여기서는 i가 n -1이 되더라도 인덱스를 벗어나지 않고 or문에 걸리게 만들어 fault 없이 프린트했다.
'기타 문제 풀이' 카테고리의 다른 글
| [백준] 11931 수 정렬하기 4 (0) | 2025.05.12 |
|---|---|
| [백준] 24262~7 시간 복잡도 (0) | 2025.04.08 |
| [백준] 10171, 10172 고양이와 개 (4) | 2024.12.24 |
| [프로그래머스] Lv.1 실패율 (3) | 2024.11.22 |
| [백준] 2743 단어 길이 재기 (1) | 2024.11.22 |