728x90
반응형
1. 문제 설명
- 문제 링크: 백준 10808번 - 알파벳 개수
- 요약: 알파벳 소문자로만 이루어진 단어 S가 주어졌을 때, 각 알파벳이 단어에 몇 개 포함되어 있는지 구하는 프로그램을 작성하세요. 출력은 'a'부터 'z'까지의 개수를 공백으로 구분하여 출력합니다.
2. 핵심 아이디어
이 문제의 핵심은 알파벳 문자를 배열의 인덱스로 변환하는 것입니다.
- 배열 생성: 알파벳 소문자는 총 26개입니다. 따라서 크기가 26인 정수 배열 int[] cnt = new int[26]을 생성합니다. (0번 인덱스는 'a', 25번 인덱스는 'z'를 의미하게 됩니다.)
- 아스키코드 활용: 컴퓨터는 문자를 숫자로 처리합니다. 소문자 'a'의 아스키코드 값을 문자에서 빼주면 해당 문자의 순서를 0~25 사이의 숫자로 얻을 수 있습니다.
- 'a' - 'a' = 0
- 'b' - 'a' = 1
- 'z' - 'a' = 25
- 순회 및 카운팅: 문자열의 각 문자를 확인하며 해당 인덱스의 값을 1씩 증가시킵니다.
3. 코드
전체 코드는 매우 간결합니다. BufferedReader를 사용하여 성능을 높인 점이 인상적이네요.
Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
// 1. 입력 효율을 위해 BufferedReader 사용
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
// 2. 알파벳 26개를 담을 카운팅 배열 선언
int[] cnt = new int[26];
// 3. 문자열을 문자 배열로 변환하여 하나씩 확인
for (char c : s.toCharArray()) {
// 핵심 로직: 현재 문자에서 'a'를 빼서 0~25 인덱스를 구함
cnt[c - 'a']++;
}
// 4. 결과 출력
for (int i : cnt) {
System.out.print(i + " ");
}
}
}
4. 코드 포인트 해설
- c - 'a': 이 수식 하나로 if문이나 switch문 없이 모든 알파벳을 제자리에 찾아 보낼 수 있습니다. 매우 효율적인 방식입니다.
- toCharArray(): 문자열의 각 문자에 접근할 때 s.charAt(i)를 사용하는 방법도 있지만, toCharArray()를 사용하면 향상된 for문(for-each)을 쓸 수 있어 가독성이 좋아집니다.
- 배열 자동 초기화: Java에서 int 배열은 생성 시 모든 요소가 0으로 자동 초기화됩니다. 따라서 별도로 0을 채워 넣을 필요가 없습니다.
5. 성능 및 복잡도
- 시간 복잡도: 문자열의 길이를 $N$이라고 할 때, 문자열을 한 번 훑으므로 **$O(N)$**입니다. 이후 크기가 26인 배열을 한 번 더 출력하므로 최종적으로는 선형 시간에 해결됩니다.
- 공간 복잡도: 입력과 상관없이 항상 크기 26인 배열을 사용하므로 $O(1)$(상수 공간)이라고 볼 수 있습니다.
6. 마치며
단순히 숫자를 세는 문제 같지만, 문자를 인덱스로 매핑하는 기술은 해시 테이블(Hash Table)의 원리와도 맞닿아 있습니다. 기초적인 문자열 문제를 통해 이 테크닉을 익혀두면 나중에 더 복잡한 문자열 알고리즘(예: 팰린드롬, 아나그램 확인 등)을 풀 때 큰 도움이 됩니다.
728x90
반응형
'Algorithm' 카테고리의 다른 글
| [LeetCode] 1775 Closest Dessert Cost(Java) (0) | 2026.03.16 |
|---|---|
| [백준] BOJ 2979 트럭 주차(Java) (0) | 2026.03.14 |
| [백준] BOJ 2309 일곱 난쟁이(Java) (0) | 2026.03.13 |
| [LeetCode] 427 Construct Quad Tree (1) | 2025.07.07 |
| [백준] BOJ 1655 가운데를 말해요(CPP) (0) | 2023.05.25 |