반응형


백준 - 단계별로 풀어보기 [1157] 단어 공부

https://www.acmicpc.net/problem/1157 

 

 

문제

 

 

알파벳 대소문자로 이루어진 단어가 입력되면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하는 문제이다.

핵심은 대문자와 소문자를 구분하지 않는것이다.

출력은 가장 많이 사용된 알파벳을 대문자로 출력하는것이고, 만약 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

 

 

풀이

 

이 문제의 경우에는 입력받은 문자열을 모두 대문자로 변경하고 풀이하는것이 여러모로 용이하다.

그렇기 때문에 STL의 transform 함수등을 사용하여 문자열 전체를 대문자로 바꾼 뒤, 배열 인덱스를 이용하여 각 알파벳이 몇번 사용되었는지 저장하는 접근 방식으로 해당 문제를 해결할 수 있다.

 

#include <algorithm>

int main() {
	string c;
	cin >> c;
	transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
	return 0;
}

 

위의 사용법은, c 문자열 전체를 대문자로 변환하여 다시 c에 저장하라는 의미를 담고 있다.

이 코드를 실행하여 먼저 문자열을 모두 대문자로 변환하고, 그 후 배열을 선언하여 각 알파벳이 몇 번 사용되었는지를 계산한다.

 

 * 윈도우의 경우 toupper만 입력해도 정상적으로 작동되지만, 리눅스, 맥의 기본 컴파일러에서는 toupper만 입력시 자료형이 ambiguous 하여 에러가 발생한다. 따라서 맥이나 리눅스 유저는 (int(*)(int))로 확실히 자료형 캐스팅을 진행하여야한다.

 

코드는 다음과 같다.

 

int a[26] = {0,};
transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
for(int i = 0; i < c.length(); i++) {
    a[c[i] - 'A']++;
}

 

위 코드가 의미하는바는 다음과 같다.

c[i]는 해당 문자열의 아스키코드를 의미하므로 c[i]가 A일경우, 'A' - 'A' = 0, B일경우, 'B' - 'A' = 1 로 처리되어 인덱스 순서대로 0부터 A, 25가 Z로 표현할 수 있다.

즉 해당 알파벳이 몇번 등장했는지 계산할 수 있는 코드이다.

 

그 후 가장 큰 값을 찾아 출력을 해주면 정상적으로 풀이가 가능하다.

 

코드

 

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
    string c;
    cin >> c;
    int max = 0;
    int cnt = 0;
    int target;
    int a[26] = {0,};
    transform(c.begin(), c.end(), c.begin(), (int(*)(int))toupper);
    for(int i = 0; i < c.length(); i++)
    {
        a[c[i] - 'A']++;
    }

    for(int i = 0; i < 26; i++)
    {
        if(max < a[i])
        {
            max = a[i];
            cnt = 0;
            target = i;
        }
        if(max == a[i])
            cnt++;
    }
    if(cnt > 1)
        cout << "?";
    else
        cout << (char)(target+'A');
    return 0;
}

 

출력을 위해서는 가장 빈도가 높았던 문자의 인덱스값에다가 아까 빼주었던 'A' 를 더해주면 다시 아스키값으로 변환된다.

이때 출력형을 char형으로 캐스팅해주지 않으면 문자의 아스키값이 나오고 문자가 나오지 않으므로 char형으로 형변환을 반드시 해주어야 한다.

평가

 

STL을 활용하여 대문자로 변환을 하면 아주 편해지는 문제이다.

STL을 활용하지 못했을 경우, if문을 사용해서 'a' << x << 'z' 과 'A' << x << 'Z' 식의 구문을 작성해야하는데, 프로그래밍 효율이 떨어진다.

transport 함수를 활용하여 대문자, 소문자로 변경하는 방법은 알아두면 문자열처리에 아주 유용할 것 같아서 정리한 포스팅이다.

정답률은 38%로 꽤 낮은 편이다.

 

본 문제에서는 transport의 활용과 ASCII 코드 값을 활용한 트릭에 대해서 짚고 넘어가면 좋을 것 같다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,