학부시절 알고리즘 강좌의 시작은 소팅이었습니다.
교수님은 한 주 정도 소팅에 대한 강의를 해주시고,
7~8가지 소팅 알고리즘을 코딩과제를 내주셨죠.
아주 흥미로운 과제였지만 동시에 지긋지긋하기도 했습니다.
'이걸 과연 어디에 써먹을까?'라고 생각도 했었는데요,
그걸 여기에 써먹게 되는군요.
현업에서 소팅알고리즘을 직접 짤 일은 거의 없습니다만,
결국엔 다 피가 되고 살이 된다고 믿고 싶습니다.
algopost에 실린 '왕초보'문제에 도전하겠습니다.
난이도는 '왕초보'인데 소팅 항목이 있어서 많은 생각을 하게 합니다.
소팅에 사용할 수 있는 최적화 알고리즘이 여러가지가 있겠습니다만,
순전히 감에 의존하여 발로 짠 답안을 공개하도록 하겠습니다. :)
문제는 영어로 되어 있어서 간단하게 한글로 의역했습니다.
문제에 소녀시대학교는 Sonyusi University입니다.
- 제목 : LECTURE
- 난도 : ★★☆☆☆ (2점/5점)
- 문제 : Lew 교수는 소녀시대학교에서 알고리즘을 가르치고 있습니다. 첫 해라 강의노트를 만드는데 많은 시간을 들이고 있죠. 다음 시간에 가르칠 recursion과 sorting를 위해 예제를 만들었는데, 그 중 하나가 무척 어렵다는 것을 알아차렸습니다. 스트링을 소팅하는 문제인데 절차는 아래와 같습니다.
1. 본래의 스트링을 2n이라고 할 때, n개로 쪼개어 각각 2글자로 만듭니다.
2. n개를 사전순으로 소팅합니다.
3. 모두 붙여서 출력합니다.
abbaaccb → ab ba ac cb → ab < ac < ba < cb → abacbacb
- 답안
#include <stdio.h>
#include <string.h>
#define FIXED_STRING_SIZE 2
static void _swap_fixed_string(char *a, char *b)
{
int i = 0;
char tmp[FIXED_STRING_SIZE] = {0, };
for (i = 0; i < FIXED_STRING_SIZE; i++) {
tmp[i] = a[i];
}
for (i = 0; i < FIXED_STRING_SIZE; i++) {
a[i] = b[i];
}
for (i = 0; i < FIXED_STRING_SIZE; i++) {
b[i] = tmp[i];
}
}
static int _compare_fixed_string(char *a, char *b)
{
int i = 0;
int tmp = 0;
for (i = 0; i < FIXED_STRING_SIZE; i++) {
tmp = a[i] - b[i];
if (tmp) return tmp;
}
return tmp;
}
static void _rebuild_heapsort(char *string, int root, int length)
{
int changed = root;
int left = (root << 1) + FIXED_STRING_SIZE;
int right = (root << 1) + (FIXED_STRING_SIZE << 1);
if (left < length
&& _compare_fixed_string(&string[changed], &string[left]) < 0)
{
changed = left;
}
if (right < length
&& _compare_fixed_string(&string[changed], &string[right]) < 0)
{
changed = right;
}
if (changed != root) {
_swap_fixed_string(&string[root], &string[changed]);
_rebuild_heapsort(string, changed, length);
}
}
static void _build_heapsort(char *string, int length)
{
int remainder = length % (FIXED_STRING_SIZE << 1);
int i;
if (remainder) {
i = (length - FIXED_STRING_SIZE) >> 1;
} else {
i = (length - (FIXED_STRING_SIZE << 1)) >> 1;
}
for (; i >= 0; i -= FIXED_STRING_SIZE) {
_rebuild_heapsort(string, i, length);
}
}
static void _sort_string(char *string, int length)
{
int i = 0;
_build_heapsort(string, length);
for (; i < length; i += FIXED_STRING_SIZE) {
int last = length - i - FIXED_STRING_SIZE;
_swap_fixed_string(string, string + last);
_rebuild_heapsort(string, 0, last);
}
}
int main(int argc, char **argv)
{
register int i = 0;
int count = 0;
scanf("%d", &count);
for (; i < count; i++) {
char string[1001] = {0, };
int length = 0;
scanf("%s", string);
if (!string) continue;
length = strlen(string);
if (!length) continue;
_sort_string(string, length);
printf("%s\n", string);
}
return 0;
}
- 문자열을 색다르게 소팅하고 싶어서 "굳이" heap sort를 사용하였습니다.
_build_heapsort()에서 문자열을 heapsort 요건에 맞게 변환하였습니다.
부모 노드 값이 자식 노드 값보다 크도록 정렬하고,
root를 뽑아 제일 뒤로 옮깁니다.
그리고 다시 heap sort에 맞게 재정렬하지요.
_rebuild_heapsort()로 재정렬합니다.
build & rebuild 과정은 아래 사이트에서 play 해보시면 도움이 될 겁니다.
https://www.cs.usfca.edu/~galles/visualization/HeapSort.html
- 문제에서는 두 글자의 스트링이라 한정했지만,
코드를 짜다보니, "2"로 코드를 제한하기 싫어서,
FIXED_STRING_SIZE를 정의하여 두 글자가 아닌 경우에도 적용할 수 있도록 하였습니다.
- 가급적이면 stdio 외에는 사용하고 싶지 않았는데,
strlen()는 그냥 사용했습니다.
귀차니즘이 문제네요.
순위는 2252위가 되었습니다.
4문제에서 하나 더 푸니 2626위에서 2252위로 374계단 올랐습니다.
이번 문제는 그간 사용해볼 기회가 없었던 heap sort를 사용한 것에 의미를 두겠습니다.
그럼 좋은 하루 보내세요~
* References
http://www.sorting-algorithms.com/
https://algospot.com/judge/problem/read/LECTURE
https://www.cs.usfca.edu/~galles/visualization/HeapSort.html
'IT' 카테고리의 다른 글
[algospot/알고리즘] 알고스팟 '왕초보' 난이도 CONVERT 풀기(C99 Default argument promotion) (1) | 2015.06.30 |
---|---|
[algospot/알고리즘] 알고스팟 알고리즘 풀어보기 (0) | 2015.06.29 |
[algospot/알고리즘] 알고스팟, '왕초보' 난이도 MISPELL 풀기 (0) | 2015.06.28 |
[algospot/알고리즘] 알고스팟, '왕초보' 난이도 ENCRYPT 풀기 (0) | 2015.06.26 |
[algospot/알고리즘] 알고스팟 접속불가, "502 Bad Gateway"는 무엇? (1) | 2015.06.25 |
[algospot/알고리즘] 알고스팟, '왕초보' 난이도 DRAWRECT 풀기 (0) | 2015.06.23 |
[algospot/알고리즘] 알고스팟, '왕초보' 난이도 ENDIANS 풀기 (0) | 2015.06.22 |
[SQLite] SQLite의 새로운 수익모델 (0) | 2015.06.21 |
[algospot/알고리즘] 알고스팟에서 HELLOWORLD 문제풀기 (0) | 2015.06.20 |
[Ubuntu/Linux] 우분투 터미널을 위한 최적화된 색상 (4) | 2015.06.19 |