본문 바로가기

컴퓨터/백준 알고리즘

백준 알고리즘 1157번: 단어 공부 C언어

문제 출처: www.acmicpc.net/problem/1157

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net

1. 코드

#include <stdio.h>
#include <string.h>


int main(void)
{
    int i, j, max, result=0, len;
    char arr[1000000];
    int cnt[26] = {0, };
    int select = 0;
    
    scanf("%s", arr);
    len = strlen(arr);
    
    for(i = 'a'; i <= 'z'; i++)
    {
        for(j = 0; j < len; j++)
        {
           if(i == arr[j])
               cnt[i-'a']++;
        }
    }
    for(i = 'A'; i <= 'Z'; i++)
    {
        for(j = 0; j < len; j++)
        {
           if(i == arr[j])
               cnt[i-'A']++;
        }
    }
    
    max = cnt[0];
    for(i = 1; i < 26; i++)
    {
        if(max < cnt[i])
        {
            max = cnt[i];
            select = i;
        }
    }
    
    for(i = 0; i < 26; i++)
    {
        if(max == cnt[i])
            result++;
    }
    
    if(result > 1)
        printf("?\n");
    else
        printf("%c", select+'A');
    return 0;
}

2. 문제 해결 과정

이 방법은 그냥 간단하다. 문자열 입력받고 알파벳 개수만큼의 배열을 선언하여 임의적으로 0을 A, 1을 B... 등등 이런 식으로 생각을 하며 해당되는 소문자와 대문자를 찾으면 배열을 증가시켜서 해당되는 알파벳이 증가됐다는 것을 인식하고 그다음은 가장 많이 증가된 부분을 찾기 위해 최댓값을 찾고 최댓값을 가지고 있는 인덱스 값을 같이 찾는다.

그리고 마지막으로 최댓값이 여러 개가 있으면 ?로 출력하라는 말이 있기에 최댓값을 이용하여 같은 값이 있는지 확인한 다음 만약 1개만 있으면 해당되는 값의 미리 찾은 최댓값의 인덱스 값을 이용하여 대문자를 출력한다. 만약 아니라면 ?를 표시한다.

이때 인덱스 값을 이용하여 알파벳 대문자를 출력하는 것은 아스키 코드를 이용한 것인데 아스키 코드에서 A는 십진수로 65이다. 그렇다면 만약 a라는 값이 많이 나와서 최대로 많이 나온 문자의 값의 인덱스 값은 0일 것이다. 그렇다면 0 + 65 = 65이기에 A가 나온다.

3. 느낀 점

처음 이 코드는 이러한 짜임새가 아니었다. 물론 방식은 똑같지만 이렇게 main 함수를 본다면 조금 많이 길어서 산만해 보인다. 그래서 이런 식으로 짰었는데

#include <stdio.h>
#include <string.h>

void count(char a[], int b[])
{
    int i, j;
    
    for(i = 'a'; i <= 'z'; i++)
    {
        for(j = 0; j < strlen(a); j++)
        {
           if(i == a[j])
               b[i-'a']++;
        }
    }
}
void COUNT(char a[], int b[])
{
    int i, j;
    
    for(i = 'A'; i <= 'Z'; i++)
    {
        for(j = 0; j < strlen(a); j++)
        {
           if(i == a[j])
               b[i-'A']++;
        }
    }    
}

int main(void)
{
    int i, j, max=0, result=0;
    char arr[1000000];
    int cnt[26] = {0, };
    int select = 0;
    
    scanf("%s", arr);
    
    count(arr, cnt);
    COUNT(arr, cnt);
    
    max = cnt[0];
    for(i = 1; i < 26; i++)
    {
        if(max < cnt[i])
        {
            max = cnt[i];
            select = i;
        }
    }
    
    for(i = 0; i < 26; i++)
    {
        if(max == cnt[i])
            result++;
    }
    if(result > 1)
        printf("?\n");
    else
        printf("%c", select+'A');
    return 0;
}

소문자와 대문자를 인식하고 배열의 값을 1씩 증가하는 것을 별도로 함수로 나누어했지만 시간이 초과되어 실패했다. 그런데 어느 부분이 시간이 많이 드는지 아직도 파악을 못했다. 나중에 정확한 이유를 알게 된다면 그 방식을 안 쓰는 방법으로 해결해보아야겠다.