1. 문제 및 예시 실행결과
이번 문제에서 문제를 두번이나 틀렸다(내 정답률 ㅠㅠ) 사실 나의 잘못이기도 하다...... 컴파일 에러도 두번이나 발생하였는데 strupr() 함수 때문이었다. 차라리 이런 컴파일 에러는 구글을 통해 고칠 수 있지만, 오늘과 같은 논리 오류는 정말 머리를 아프게 한다...... 다음은 문제와 예시 실행 결과이다.
출처: https://www.acmicpc.net/problem/1157
문제를 보면 대소문자를 구별하지 않는데, 이 부분을 처리할 때 컴파일 에러가 발생하였다. 물론 논리 오류는 여기서 발생하지 않았다. 이는 다음에 설명할 것이다.
2. 풀이 과정
풀이의 알고리즘은 이렇다. 입력받은 문자열을 전부 대문자로 바꾼 후, 해당 문자의 등장횟수를 입력하는 배열에 등장횟수를 저장한다. 등장횟수에서 최댓값을 찾아 해당하는 알파벳을 출력한다.
등장횟수를 입력하는 배열을 선언하는 것은 간단했다. 모든 문자는 아스키코드를 가지고 있고 이에 해당하는 자리에 생성하면 되기 때문이다. python에 경우 dictionary 자료형을 사용하면 간단했겠지만, C언어는 약간의 연산을 해야한다. 사실 연산이라고 해봤자 'A'문자열의 아스키코드값을 해당 문자에서 빼주고 그 값을 그대로 인덱스에 사용하면 되기 때문에 별 상관이 없다. 이를 사용한 나의 코드이다.
#include <stdio.h>
#include <string.h>
#define SIZE 100000
int main(void) {
char input[SIZE];
int count[26] = { 0 };
scanf("%s", input);
strupr(input);
for (int i = 0; input[i]; i++)
count[input[i] - 'A']++;
char ans = 'A' + 0;
int max = count[0];
for (int i = 1; i < 26; i++) {
if (max < count[i]){
max = count[i];
ans = 'A' + i;
}
else if (max == count[i] && max) {
ans = '?';
break;
}
}
printf("%c", ans);
}
위의 코드는 컴파일 에러가 나게 된다. 이유는 strupr() 함수는 리눅스 계열에 포함되지 않은 함수이고, 백준 알고리즘의 체점은 리눅스에서 이루어지기 때문이다. 따라서 입력받은 문자열을 다음과 같은 방법을 사용하여 전부 대문자로 바꿔주었다.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 1000000
int main(void) {
char input[SIZE];
int count[26] = { 0 };
scanf("%s", input);
for (int i = 0; input[i]; i++) {
if(islower(input[i]))
input[i] = toupper(input[i]);
}
for (int i = 0; input[i]; i++)
count[input[i] - 'A']++;
char ans = 'A' + 0;
int max = count[0];
for (int i = 1; i < 26; i++) {
if (max < count[i]){
max = count[i];
ans = 'A' + i;
}
else if (max == count[i] && max) {
ans = '?';
break;
}
}
printf("%c", ans);
}
고수 분들은 알겠지만, 예외가 존재했다...... 마지막에 ans를 '?'로 지정해주는 코드의 조건문을 보면 max가 0이 아닐때만을 거르고 있다. 그렇기 때문에 'aabbccccc' 와 같은 경우도 '?' 를 출력하게 된다. 이유는 앞에 aabb가 1도 아니면서 서로 같은 수이기 때문에 저 코드는 그대로 반복문을 종료하고 '?'을 출력하기 때문이다. count배열의 끝까지 검사를 해야한다고 생각하였고 for문의 중간에 상태를 표시하는 변수를 넣어야겠다고 판단했다. 다음은 오류를 고친 정답 코드이다.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 1000000
int main(void) {
char input[SIZE];
int count[26] = { 0 };
int state = 1;
scanf("%s", input);
for (int i = 0; input[i]; i++) {
if(islower(input[i]))
input[i] = toupper(input[i]);
}
for (int i = 0; input[i]; i++)
count[input[i] - 'A']++;
char ans = 'A' + 0;
int max = count[0];
for (int i = 1; i < 26; i++) {
if (max < count[i]){
max = count[i];
ans = 'A' + i;
state = 1;
}
else if (max == count[i] && max) {
state = 0;
}
}
if (state)
printf("%c", ans);
else
printf("?");
}
3. 결어
문제를 틀리고 그것을 해결했다는 것은 나름 내가 성장했다는 것을 의미한다고 생각하고 나를 항상 위안한다. 이제 백준 알고리즘만이 아닌 만들어 놓은 자료구조 카테고리에도 자료를 올렸으면 좋겠다.
'programming > 알고리즘 풀이' 카테고리의 다른 글
[백준 알고리즘] 2292번 - 벌집 (0) | 2020.07.15 |
---|---|
[백준 알고리즘] 2941번 - 크로아티아 알파벳 (0) | 2020.06.29 |
[백준 알고리즘] 2675번 - 문자열 반복 (0) | 2020.06.27 |
[백준 알고리즘] 10809번 - 알파벳 찾기 (0) | 2020.06.24 |
[백준 알고리즘] 11720번 - 숫자의 합 (0) | 2020.06.24 |