본문 바로가기
Java

[백준] 코딩테스트 문제 1157: 단어 공부

by 리슈다 2026. 2. 25.

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

import java.util.*;
import java.io.*;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine().toLowerCase();
        int[] alphabet = new int[26];

        Arrays.fill(alphabet, 0);
        int index;
        int max = -1;
        int tempMax = 0;
        int maxIndex = 0;
        int maxAlphabet = 0;

        for(int i = 0; i < str.length(); i++){
            index = str.charAt(i) - 'a';
            alphabet[index]++;
            max = Math.max(max, alphabet[index]);
            if(max > tempMax) {
                maxIndex = index;
                maxAlphabet = alphabet[index];
                tempMax = max;
            }
        }

        int cnt = 0;
        for(int i = 0; i < alphabet.length; i++){
            if(alphabet[i] >= maxAlphabet){
                cnt++;
            }
        }

        char result = (cnt > 1) ? '?' : (char)(maxIndex + 'A');
        System.out.println(result);
    }
}

문제 접근법은 처음에 생각했는데 그걸 코드로 구현하기까지가 오래 걸림.

이전에 풀었던 10809: 알파벳 찾기 문제를 참고해서 알파벳 갯수만큼 배열 만들고, 그 배열 안의 값을 빈도수로 생각해서 빈도수의 최댓값을 기준으로 답 출력하는 방식

계속 테스트 해보면서 코드 조금씩 수정하다보니까 변수도 많아지고, 가독성도 점점 떨어짐

주석 달려다가 귀찮아서 지피티한테 부탁함

package baekjoon;
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 입력 문자열을 소문자로 통일 (대소문자 구분하지 않기 위해)
        String str = br.readLine().toLowerCase();

        // a~z 빈도수를 저장할 배열 (0: a, 1: b, ... 25: z)
        int[] alphabet = new int[26];

        // int 배열은 기본값이 0이라 사실 필요 없지만, 명시적으로 0으로 초기화
        Arrays.fill(alphabet, 0);

        int index;          // 현재 문자가 alphabet 배열에서 어느 칸인지 (0~25)
        int max = -1;       // 지금까지 등장한 알파벳 빈도수의 최댓값 (max값)
        int tempMax = 0;    // max 값이 갱신될 때를 감지하기 위한 변수 (현재 기록된 최대 빈도)
        int maxIndex = 0;   // 최댓값을 가진 알파벳의 인덱스 (0~25)
        int maxAlphabet = 0;// 최댓값을 가진 알파벳의 실제 빈도수

        // 1) 문자열을 한 번 순회하면서 알파벳 빈도수를 센다
        for (int i = 0; i < str.length(); i++) {
            // 'a'를 0으로 맞춰서 인덱스로 변환
            index = str.charAt(i) - 'a';

            // 해당 알파벳 카운트 증가
            alphabet[index]++;

            // 현재까지의 최대 빈도(max) 갱신
            max = Math.max(max, alphabet[index]);

            // max가 이전에 기록된 tempMax보다 커졌다면
            // (즉, "새로운 단독 1등"이 생긴 순간)
            if (max > tempMax) {
                maxIndex = index;            // 1등 알파벳의 인덱스 저장
                maxAlphabet = alphabet[index]; // 1등 알파벳의 빈도 저장
                tempMax = max;              // tempMax도 최신 max로 갱신
            }
        }

        // 2) 최댓값(maxAlphabet)과 같은 빈도를 가진 알파벳이 몇 개인지 센다
        int cnt = 0;
        for (int i = 0; i < alphabet.length; i++) {
            // maxAlphabet 이상이면 카운트 (사실 == 로 해도 됨)
            if (alphabet[i] >= maxAlphabet) {
                cnt++;
            }
        }

        // 3) 최댓값이 여러 개면 '?' 출력, 아니면 해당 알파벳을 대문자로 출력
        char result = (cnt > 1) ? '?' : (char)(maxIndex + 'A');
        System.out.println(result);
    }
}

 

그리고 코드 피드백과 더 깔끔한 풀이도 제공받음

import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine().toUpperCase(); // 대문자로 통일

        int[] cnt = new int[26]; // A~Z 빈도수

        // 1) 빈도 계산
        for (int i = 0; i < str.length(); i++) {
            cnt[str.charAt(i) - 'A']++;
        }

        // 2) 최대값과 그 최대값을 가진 문자를 찾고, 동점 여부 확인
        int max = -1;
        char answer = '?';
        for (int i = 0; i < 26; i++) {
            if (cnt[i] > max) {
                max = cnt[i];
                answer = (char) (i + 'A');
            } else if (cnt[i] == max) {
                answer = '?'; // 동점 발생
            }
        }

        System.out.println(answer);
    }
}

1. Arrays.fill(alphabet, 0)은 불필요. new int[26]은 자동으로 0으로 초기화.

2. max, tempMax, maxAlphabet 중복 역할.

 max가 이미 '최대빈도'인데 tempMax, maxAlphabet으로 또 관리하니까 변수가 늘어남

3. 동점 체크 로직이 >=라서 의도가 헷갈릴 수 있음. ==가 더 정확하고 의도가 선명

4. '최대 빈도 알파벳의 인덱스'는 빈도 계산 후 한 번 더 훑어서 찾는게 오히려 더 명확