Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 코딩테스트
- 플로이드-워셜
- 1일1코테
- 코테공부
- 파이썬
- 자바스크립트
- 연결 리스트
- C
- 프로그래머스
- 99클럽
- 알고리즘
- 데이터베이스
- 웹
- 티스토리챌린지
- til
- 운영체제
- 개발자취업
- 인접 행렬
- 프로그래밍 언어
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 자료구조
- 갭체크
- Java
- 오블완
- 항해99
- 코딩테스트준비
- 자바
- 코딩테스트사이트추천
- 개발자루틴
- 코드트리
Archives
- Today
- Total
와드의 블로그
2941번: 크로아티아 알파벳 본문
문제
예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없어서, 다음과 같이 변경하여 입력했습니다.
- c= (č)
- c- (ć)
- dz= (dž)
- d- (đ)
- lj (lj)
- nj (nj)
- s= (š)
- z= (ž)
단어가 주어졌을 때, 이 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 구하는 프로그램을 작성하는 문제입니다. 목록에 없는 알파벳은 한 글자씩 센다고 가정합니다.
- 입력: 첫째 줄에 최대 100글자의 단어가 주어집니다. 알파벳 소문자와 '-', '='로만 이루어져 있습니다.
- 출력: 입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력합니다.
링크: https://www.acmicpc.net/problem/2941
풀이 1: 인덱스 조작과 조건문을 활용한 순차 탐색
문자열을 처음부터 끝까지 한 번 순회하면서, 특정 문자를 만났을 때 바로 뒤의 문자들을 확인(Lookahead)하여 크로아티아 알파벳 묶음을 찾아내는 직관적인 시뮬레이션 방식입니다.
- 인덱스(idx) 기반 탐색: for문 대신 while문과 idx 변수를 사용하여, 여러 글자가 하나의 알파벳으로 취급될 때 인덱스를 유연하게 건너뛸 수 있도록 설계합니다.
- 미리 보기(Lookahead) 및 경계 검사:
- 현재 문자 c가 크로아티아 알파벳의 시작 문자인 c, d, l, n, s, z 중 하나라면, 이어지는 다음 문자를 확인합니다.
- 이때 StringIndexOutOfBoundsException 오류를 방지하기 위해 반드시 idx < s.length() - 1 (두 글자 확인 시) 또는 idx < s.length() - 2 (세 글자인 dz= 확인 시)와 같이 안전하게 문자열 길이를 검사합니다.
- 인덱스 건너뛰기:
- 만약 조건을 만족하여 두 글자가 하나의 알파벳으로 묶인다면, idx += 1을 통해 다음 문자를 건너뜁니다.
- 세 글자(dz=)가 묶인다면 idx += 2를 통해 두 문자를 건너뜁니다.
- 정답 카운트: 분기문을 통과한 후 기본적으로 idx++가 한 번 더 실행되므로 다음 검사 위치로 알맞게 이동되며, 어떤 경우든 알파벳 하나를 센 것이므로 ans++를 수행합니다.
코드 1
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = br.readLine();
int ans = 0;
int idx = 0;
while (idx < s.length()) {
char c = s.charAt(idx);
if (c == 'c') {
if (idx < s.length() - 1 && (s.charAt(idx + 1) == '=' || s.charAt(idx + 1) == '-')) {
idx += 1;
}
} else if (c == 'd') {
if (idx < s.length() - 1 && s.charAt(idx + 1) == '-') {
idx += 1;
} else if (idx < s.length() - 2 && s.charAt(idx + 1) == 'z' && s.charAt(idx + 2) == '=') {
idx += 2;
}
} else if (c == 'l') {
if (idx < s.length() - 1 && s.charAt(idx + 1) == 'j') {
idx += 1;
}
} else if (c == 'n') {
if (idx < s.length() - 1 && s.charAt(idx + 1) == 'j') {
idx += 1;
}
} else if (c == 's') {
if (idx < s.length() - 1 && s.charAt(idx + 1) == '=') {
idx += 1;
}
} else if (c == 'z') {
if (idx < s.length() - 1 && s.charAt(idx + 1) == '=') {
idx += 1;
}
}
idx++;
ans++;
}
bw.write(ans + "");
bw.flush();
}
}
풀이 2: replaceAll 메서드를 활용한 문자열 치환
자바의 내장 문자열 치환 메서드인 replaceAll(또는 replace)을 활용하여, 코드를 극단적으로 단축시키는 방식입니다.
- 배열 선언: 8개의 크로아티아 알파벳을 문자열 배열(croatian)에 미리 정의합니다.
- 문자열 치환: 배열을 순회하면서 입력받은 문자열 s 내부에 크로아티아 알파벳과 일치하는 패턴이 있다면, 이를 임의의 한 글자(예: "a" 또는 "*" 등)로 전부 치환합니다.
- 예: ljes=njak -> aes=njak (lj 치환) -> aea=njak (s= 치환) -> aeaaak (nj 치환)
- 길이 도출: 모든 치환이 끝나면 크로아티아 알파벳은 각각 한 글자로 뭉쳐지고, 나머지 일반 알파벳도 원래 한 글자이므로, 최종적으로 남은 문자열의 길이(s.length())가 곧 전체 알파벳의 개수가 됩니다.
코드 2
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
// 탐색할 크로아티아 알파벳 목록
String[] croatian = {"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
// 목록을 순회하며 일치하는 문자열을 한 글자("a")로 치환
for (String val : croatian) {
s = s.replaceAll(val, "a");
}
// 치환이 완료된 문자열의 길이가 정답
System.out.println(s.length());
}
}
알고리즘 분류
구현 (Implementation), 문자열 (String)
'PS > B.O.J' 카테고리의 다른 글
| 1969번: DNA (0) | 2026.04.10 |
|---|---|
| 3613번: Java vs C++ (0) | 2026.04.10 |
| 1929번: 소수 구하기 (0) | 2026.04.08 |
| 단어 나누기 (0) | 2026.04.07 |
| 16637번: 괄호 추가하기 (0) | 2026.04.06 |