◎ 자료구조와 알고리즘/백준(BOJ) 문제풀이

[백준 / BOJ] 1157번 단어 공부 (C++, Python)

Reo 2022. 1. 17. 09:52
반응형

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

 

1157번: 단어 공부

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

www.acmicpc.net


문제


문제 풀이

C++ 상세 풀이

더보기
void solution(string str)
{
    int max = 0;
    int cnt = 0, val = 0;
    int len = str.length();

    for (int i = 0; i < len; i++)
    {
        alp[str[i] - 65]++;
    }

    for (int i = 0; i < 26; i++)
    {
        if (max < alp[i])
        {
            val = i;
            max = alp[i];
            cnt = 0;
        }
        if (max == alp[i])
            cnt++;
    }

    if (cnt > 1)
        cout << "?";
    else
        cout << (char)(val + 'A');
}

우선 아이디어는 대소문자를 구분하지 않으니 모든 문자를 대문자나 소문자로 변경한 다음 alp[26]배열에서 알파벳에 대응하는 인덱스의 값을 1씩 늘리는 방향으로 구현했다.

// 왜 안되나 했더니, 맥이나 리눅스에서는 자료형이 모호해져서 (int(*)(int))을 해줘야 한단다. 잘 모르겠다.
std::transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);

C++을 이용하는 만큼, <algorithm> 헤더파일을 추가해 구현하였다. transform을 이용하면 쉽게 string의 요소들을 한꺼번에 바꿀 수 있다. 이로써 toupper로 모두 대문자로 만든 후 최댓값을 찾는 알고리즘을 구현하였다. 코드를 구현할 때는 몰랐는데 <algorithm>에 바로 배열이나 vector의 최댓값을 찾는 사기적인 방법이 있으니 그것으로 구현하는 것도 좋을 듯 하다.

Python 상세 풀이

더보기

파이썬은 주석으로 상세하게 달아놨으니 해당 부분을 참고하는 것이 좋겠다.

 

# C++식으로 똑같이 짜기보다는, 파이썬의 사기성을 이용해보자.

text = input().upper()

# 중복된 단어 없앰
rm_overlap = list(set(text))
# 중복 셀 리스트
overlap = []

# 중복을 없앤 리스트를 기준으로 원래 문자열의 개수를 overlap에 저장 
# ex) zZa -> Z, a 순서대로, Z Z A 이므로 2, 1이 들어감
for i in rm_overlap:
    overlap.append(text.count(i))

# max 값을 가진 요소가 2개 이상 있으면 중복이므로 ? 출력
if overlap.count(max(overlap)) > 1:
    print("?")
else: # 아니라면 overlap의 max요소의 인덱스를 뽑아 중복된 단어 없앤 리스트의 단어 출력
    # ex) ZZA, Z/A, 2/1, 2의 인덱스는 0, Z의 인덱스도 0임.
    print(rm_overlap[overlap.index(max(overlap))])

 

C++ 코드 전문

 

Python 코드 전문

 

소감

나중에 보니 코드가 너무 난잡한 것 같다. 다음에 다시 풀어봐야겠다.

반응형