📖 문제
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
💡 풀이 방식
• 사용자 정의 정렬
1. 파일명을 HEAD / NUMBER / TAIL 로 3등분하고, 이를 (머리, 숫자, 꼬리)를 저장하는 객체 배열에 저장한다.
for(int i = 0 ; i < files.length ; i++) {
String file = files[i];
String head = "";
String number = "";
String tail = "";
// 1. HEAD 부분 자르기 & 숫자로 시작하는 부분 인덱스 찾기
int numIdx = 0; // 숫자로 시작하는 인덱스
for(int j = 0 ; j < file.length() ; j++) {
if(Character.isDigit(file.charAt(j))) {
head = file.substring(0, j);
numIdx = j;
break;
}
}
// 2. NUMBER 부분 자르기 & 숫자로 끝나는 부분(=TAIL 시작 부분) 인덱스 찾기
int tailIdx = 0;
for(int j = numIdx ; j < file.length() ; j++) {
if(Character.isDigit(file.charAt(j))) {
number += file.charAt(j);
}
else { // 더 이상 숫자가 아니면, TAIL 부분 시작
tailIdx = j;
break;
}
}
if(tailIdx == 0) // TAIL이 없는 경우
tail = "";
else
tail = file.substring(tailIdx);
infos[i] = new Info(head, number, tail); // 객체 배열에 값 저장
}
2. 문제의 조건에 맞게 객체 배열을 정렬한다.
class Info implements Comparable<Info> {
String head, num, tail;
public Info(String head, String num, String tail) {
this.head = head;
this.num = num;
this.tail = tail;
}
@Override
public int compareTo(Info info) {
if(this.head.equalsIgnoreCase(info.head)) {
if(Integer.parseInt(this.num) != Integer.parseInt(info.num)) { // 2. 대소문자 이외 차이 없는 경우, NUMBER 숫자 순 오름차순 정렬
return Integer.parseInt(this.num) - Integer.parseInt(info.num);
}
}
return this.head.toUpperCase().compareTo(info.head.toUpperCase()); // 조건1. HEAD 부분 기준 사전 순 오름차순 정렬
}
}
3. 정렬한 배열을 출력한다.
💥 유의사항
1. 꼬리 부분 (TAIL)이 공백인 경우를 잘 처리해줘야 한다.
꼬리 부분의 시작 인덱스가 0일 때 꼬리 부분이 공백임을 의미하므로, 이 때 꼬리 부분은 빈 문자열로 저장한다.
그게 아니라면, 꼬리 부분 시작 인덱스부터 끝까지를 잘라 꼬리로 지정한다.
if(tailIdx == 0) // TAIL이 없는 경우
tail = "";
else
tail = file.substring(tailIdx);
(그냥 file.substring(tailIdx)만 했을 떈, 꼬리 부분이 공백인 경우 tailIdx가 여전히 0이므로 문자열이 1번 더 반복되는 사태가 발생했다,,, F - 15 F-15 이렇게...)
2. 숫자 부분을 객체로 저장할 때 int형이 아닌 String형으로 저장해야 한다.
그렇지 않으면 0으로 시작하는 숫자의 0들이 누락된 상태로 출력되기 때문이다.
🔺 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
import java.util.*;
class Solution {
static String[] files;
static Info[] infos;
public String[] solution(String[] files) {
this.files = files;
infos = new Info[files.length];
for(int i = 0 ; i < files.length ; i++) {
String file = files[i];
String head = "";
String number = "";
String tail = "";
// 1. HEAD 부분 자르기 & 숫자로 시작하는 부분 인덱스 찾기
int numIdx = 0; // 숫자로 시작하는 인덱스
for(int j = 0 ; j < file.length() ; j++) {
if(Character.isDigit(file.charAt(j))) {
head = file.substring(0, j);
numIdx = j;
break;
}
}
// 2. NUMBER 부분 자르기 & 숫자로 끝나는 부분(=TAIL 시작 부분) 인덱스 찾기
int tailIdx = 0;
for(int j = numIdx ; j < file.length() ; j++) {
if(Character.isDigit(file.charAt(j))) {
number += file.charAt(j);
}
else { // 더 이상 숫자가 아니면, TAIL 부분 시작
tailIdx = j;
break;
}
}
if(tailIdx == 0) // ⭐ TAIL이 없는 경우 처리
tail = "";
else
tail = file.substring(tailIdx);
infos[i] = new Info(head, number, tail);
}
Arrays.sort(infos); // 사용자 정의 정렬
String[] answer = new String[files.length];
for(int i = 0 ; i < answer.length ; i++) {
answer[i] = infos[i].head + infos[i].num + infos[i].tail;
}
return answer;
}
}
class Info implements Comparable<Info> {
String head, num, tail;
public Info(String head, String num, String tail) {
this.head = head;
this.num = num;
this.tail = tail;
}
@Override
public int compareTo(Info info) {
if(this.head.equalsIgnoreCase(info.head)) {
if(Integer.parseInt(this.num) != Integer.parseInt(info.num)) { // 조건2. 대소문자 이외 차이 없는 경우, NUMBER 숫자 순 오름차순 정렬
return Integer.parseInt(this.num) - Integer.parseInt(info.num);
}
}
return this.head.toUpperCase().compareTo(info.head.toUpperCase()); // 조건1. HEAD 부분 기준 사전 순 오름차순 정렬
}
}
|
cs |
➕ 다른 풀이 방식
- 美친 풀이 발견
import java.util.*;
import java.util.regex.*;
class Solution {
public String[] solution(String[] files) {
Pattern p = Pattern.compile("([a-z\\s.-]+)([0-9]{1,5})");
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
Matcher m1 = p.matcher(s1.toLowerCase());
Matcher m2 = p.matcher(s2.toLowerCase());
m1.find();
m2.find();
if(!m1.group(1).equals(m2.group(1))) {
return m1.group(1).compareTo(m2.group(1));
} else {
return Integer.parseInt(m1.group(2)) - Integer.parseInt(m2.group(2));
}
}
});
return files;
}
}
- 객체 대신 2차원 배열에 값 저장하시고, 정렬 시 람다식을 활용한 정렬 (Comparator<>() compare(Obj o1, Obj o2) 비교)
[프로그래머스] 파일명 정렬(Java 자바)
https://programmers.co.kr/learn/courses/30/lessons/17686?language=java# 코딩테스트 연습 - [3차] 파일명 정렬 파일명 정렬 세 차례의 코딩 테스트와 두 차례의 면접이라는 기나긴 블라인드 공채를 무사히 통과해
tmdrl5779.tistory.com
velog
velog.io
- 초간단 풀이,,,,,!!!
[Programmers] 파일명 정렬 (Java)
코딩테스트 연습 - [3차] 파일명 정렬 파일명 정렬 세 차례의 코딩 테스트와 두 차례의 면접이라는 기나긴 블라인드 공채를 무사히 통과해 카카오에 입사한 무지는 파일 저장소 서버 관리를 맡게
subin-0320.tistory.com
💦 어려웠던 점
1시간 소요,,
- 코드 작성하는데 30분, 위의 2가지 유의사항 처리하느라 30분 정도 더 걸린 것 같다. 시간 더 짧게 할 수 있었는데!!
- Character.isDigit()이랑 eqaulsIgnoreCase()를 쓸 생각을 하지 않았다면,,,, 시간이 더 오래 걸렸을 것 같다.
- 문자열끼리 비교할 때는 compareTo() 쓴 거... 잘 생각했다!!
🧐 새로 알게 된 내용
다른 사람들 풀이를 보니 내가 얼마나 길고.. 오래 걸려 풀었는지 확인할 수 있었다ㅋㅋ
다음에는 람다식도 활용해보고 더 빠르게 코드 길이를 줄여 풀 수 있도록 해보겠다,.
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |
'코테 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/Level3] 징검다리 건너기 (JAVA) (0) | 2024.03.08 |
---|---|
[프로그래머스/Level3] 모두 0으로 만들기 (JAVA) (0) | 2024.03.06 |
[프로그래머스/Level2] 외벽 점검 (JAVA) (1) | 2024.03.05 |
[프로그래머스/Level2] 쿼드압축 후 개수 세기 (JAVA) (0) | 2024.03.05 |
[프로그래머스/Level2] 문자열 압축 (JAVA) (0) | 2024.03.04 |