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
- 코딩테스트사이트추천
- 개발자취업
- 파이썬
- 자바스크립트
- til
- 자료구조
- 99클럽
- 데이터베이스
- 1일1코테
- 항해99
- 플로이드-워셜
- 프로그래밍 언어
- 코딩테스트준비
- 코테공부
- Java
- 코딩테스트
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 인접 행렬
- C
- 웹
- 프로그래머스
- 연결 리스트
- 티스토리챌린지
- 자바
- 오블완
- 코드트리
- 갭체크
- 운영체제
- 개발자루틴
- 알고리즘
Archives
- Today
- Total
와드의 블로그
2870번: 수학숙제 본문
문제
종이에서 숫자만 찾아서 비내림차순으로 정렬하는 문제입니다. 글자는 알파벳 소문자와 숫자로만 이루어져 있습니다. 숫자의 앞에 0이 있는 경우에는 생략할 수 있습니다. (예: 01a2b34 -> 1, 2, 34)
- 입력: 첫째 줄에 종이의 줄 수 N (1 ≤ N ≤ 100)이 주어집니다. 둘째 줄부터 N개의 줄에 걸쳐 각 줄에 글자가 주어집니다. (각 줄의 길이는 최대 100)
- 출력: 찾은 숫자를 한 줄에 하나씩 오름차순으로 출력합니다.
링크: https://www.acmicpc.net/problem/2870
풀이 1: StringBuilder 활용
문자열을 한 글자씩 순회하며 숫자인 경우 StringBuilder에 담고, 알파벳을 만나면 처리하는 방식입니다. 숫자 앞에 붙은 0을 제거하기 위해 deleteCharAt(0)을 사용하였습니다. 숫자의 길이가 매우 길어질 수 있으므로 String 형태로 유지하며 커스텀 정렬을 수행합니다.
다만, StringBuilder의 첫 번째 인덱스(deleteCharAt(0))를 삭제하게 되면 내부 배열의 모든 요소들을 한 칸씩 앞으로 당겨야 하므로 삭제가 일어날 때마다 오버헤드가 발생할 수 있습니다.
코드 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));
int n = Integer.parseInt(br.readLine());
List<String> list = new ArrayList<>();
while (n-- > 0) {
String s = br.readLine();
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (c >= '0' && c <= '9') {
sb.append(c);
} else if (sb.length() > 0) {
// 맨 앞의 0 제거
while (sb.length() > 0 && sb.charAt(0) == '0') {
sb.deleteCharAt(0);
}
if (sb.length() == 0)
list.add("0");
else
list.add(sb.toString());
sb.setLength(0);
}
}
// 문자열 끝이 숫자로 끝난 경우의 나머지 처리
if (sb.length() > 0) {
while (sb.length() > 0 && sb.charAt(0) == '0') {
sb.deleteCharAt(0);
}
if (sb.length() == 0)
list.add("0");
else
list.add(sb.toString());
}
}
// 숫자의 길이가 길 수 있으므로 문자열 기반의 커스텀 정렬 수행
Collections.sort(list, (s1, s2) -> {
if (s1.length() == s2.length()) {
return s1.compareTo(s2);
}
return s1.length() - s2.length();
});
for (String s : list) {
bw.write(s + "\n");
}
bw.flush();
bw.close();
br.close();
}
}
풀이 2: 인덱스 상태 기록 및 슬라이싱
deleteCharAt(0)으로 인한 배열 이동(Shift) 오버헤드를 막기 위해 **인덱스 슬라이싱(substring)**을 활용한 방식입니다. 반복문 내부에서 인덱스를 강제로 조작하지 않고 상태 변수(start)를 사용하여 안정적으로 구현했습니다.
- 상태 기록: 문자열을 순회하며 숫자를 만나면 해당 시작 인덱스(start)를 기록해 둡니다.
- 일괄 처리: 알파벳을 만나거나 문자열의 끝(i == len)에 도달했을 때, 기록된 start가 있다면 숫자 구간이 끝난 것이므로 문자열 슬라이싱을 수행합니다.
- 0 건너뛰기: 삭제 연산을 하는 대신, 시작 인덱스(nonZeroIdx)를 뒤로 이동시키며 불필요한 0을 건너뛴 후 s.substring(nonZeroIdx, i)로 한 번에 잘라냅니다.
코드 2
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));
int n = Integer.parseInt(br.readLine());
List<String> list = new ArrayList<>();
while (n-- > 0) {
String s = br.readLine();
int len = s.length();
int start = -1; // 숫자가 시작되는 인덱스 저장
// 문자열의 끝부분 처리를 위해 조건식을 i <= len 으로 설정
for (int i = 0; i <= len; i++) {
// 문자열 끝에 도달했거나 숫자가 아닌(알파벳인) 경우
if (i == len || (s.charAt(i) < '0' || s.charAt(i) > '9')) {
// 이전에 모아둔 숫자가 있다면 처리
if (start != -1) {
int nonZeroIdx = start;
// 맨 앞의 0(Leading Zeros) 건너뛰기
// 숫자 전체가 0인 경우를 위해 마지막 인덱스(i - 1)는 남겨둠
while (nonZeroIdx < i - 1 && s.charAt(nonZeroIdx) == '0') {
nonZeroIdx++;
}
// 유효한 숫자 부분만 리스트에 추가
list.add(s.substring(nonZeroIdx, i));
start = -1; // 다음 숫자를 찾기 위해 상태 초기화
}
} else {
// 숫자인 경우 처음 시작점만 기록
if (start == -1) {
start = i;
}
}
}
}
// 숫자의 길이가 길 수 있으므로 문자열 기반의 커스텀 정렬 수행
Collections.sort(list, (s1, s2) -> {
if (s1.length() == s2.length()) {
return s1.compareTo(s2);
}
return s1.length() - s2.length();
});
for (String s : list) {
bw.write(s + "\n");
}
bw.flush();
bw.close();
br.close();
}
}
알고리즘 분류
문자열 처리 (String), 정렬 (Sorting)
'PS > B.O.J' 카테고리의 다른 글
| 3473번: 교수가 된 현우 (0) | 2026.03.23 |
|---|---|
| 10709번: 기상캐스터 (0) | 2026.03.22 |
| 4659번: 비밀번호 발음하기 (0) | 2026.03.22 |
| 2910번: 빈도 정렬 (0) | 2026.03.22 |
| 2828번: 사과 담기 게임 (1) | 2026.03.22 |