코딩테스트/Java

(2018카카오) 파일명정렬 Java

SK_MOUSE 2021. 3. 18. 14:55
반응형

채점하기를 하면 계속 오류가 난다.

정규표현식은 잘 설정했는데 어디가 문제인지 모르겠다.

 

https://programmers.co.kr/learn/courses/30/lessons/17686

1. 정규표현식

2. Compartor 다중조건 비교

 

 

정규표현식


 

  • HEAD는 숫자가 아닌 문자로 이루어져 있으며, 최소한 한 글자 이상이다.
  • NUMBER는 한 글자에서 최대 다섯 글자 사이의 연속된 숫자로 이루어져 있으며, 앞쪽에 0이 올 수 있다. 0부터 99999 사이의 숫자로, 00000이나 0101 등도 가능하다.
  • TAIL은 그 나머지 부분으로, 여기에는 숫자가 다시 나타날 수도 있으며, 아무 글자도 없을 수 있다.

 

소스 파일 저장소에 저장된 파일명은 100 글자 이내로, 영문 대소문자, 숫자, 공백(" "), 마침표("."), 빼기 부호("-")만으로 이루어져 있다. 파일명은 영문자로 시작하며, 숫자를 하나 이상 포함하고 있다.

 

다음과 같다.

 

Head

([a-zA-Z\\s\\.\\-]+)

정확하지는 않지만 다음과 같이도 사용해도 통과 되더라. (\D+)

 

 

Number

([0-9]{1,5})

다음과 같이도 표현할 수 있다.(\d{1,5})

 

Tail

(.*)

 

 

 

 

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    class Val{
        String head;
        String num;
        String tail;
        Val(String h, String n, String t){
            head = h;
            num = n;
            tail =t;
        }
    }
    public String[] solution(String[] files) {
        List<Val> list = new LinkedList<>();
        for(String s : files){
            Pattern p = Pattern.compile("([a-zA-Z\\s\\.\\-]+)([0-9]{1,5})(.*)");
            Matcher m = p.matcher(s);
            while(m.find()) {
                if(m.group(3).isEmpty())
                    list.add(new Val(m.group(1),m.group(2), ""));
                else
                list.add(new Val(m.group(1),m.group(2), m.group(3)));
            }
        }

        Comparator<Val> sort = new Comparator<Val>() {
            @Override
            public int compare(Val o1, Val o2) {
                int result = o1.head.toLowerCase().compareTo(o2.head.toLowerCase());

                if ( result == 0 ) {
                    // 문자열이 같은 경우 숫자를 비교한다.
                    result = Integer.parseInt(o1.num)-Integer.parseInt(o2.num);
                }
                return result;
            }
        };

        Collections.sort(list, sort);
        String[] answer = new String[files.length];
        for (int i=0; i<list.size();i++){
            answer[i]=list.get(i).head+list.get(i).num+list.get(i).tail;
        }
        return answer;
    }
}

 

Comparator(다중조건 비교)


 

그리고 비교하는 부분이 중요하다. 처음에는 아래와 같이 작성했었다. 다중조건문으로 비교하는것이다.

Comparator<Val> sort = new Comparator<Val>() {
            @Override
            public int compare(Val o1, Val o2) {
                if(o1.head.toLowerCase().compareTo(o2.head.toLowerCase())>0){
                    return 2;
                }else if(o1.head.toLowerCase().compareTo(o2.head.toLowerCase())<0){
                    return -2;
                }else{//같으면
                    return Integer.parseInt(o1.num) >= Integer.parseInt(o2.num) ? 1 : -1;
                }
            }
        };

하지만 이렇게 작성하는 경우, 우선순위에서 문제가 발생할 여지가 있다.

 

그러므로 문제점은.. else일때 문제일것같아서 고쳐봤다. 해결완료.

else{//같으면(수정 전)
                    return Integer.parseInt(o1.num) >= Integer.parseInt(o2.num) ? 1 : -1;
                }
                
//변환
else{//같으면(수정 후)
                    return Integer.parseInt(o1.num) - Integer.parseInt(o2.num);
                }

수정 전 처럼 작성했으면 같은 Head문자열일때 Number가 두개끼리는 비교가 가능하다.

예시) test100, test200 이라면 {test100 : -1} , {test200 : 1}

 

하지만 2개이상인 경우에는 문제가 된다.

예시) test100, test200, test300 이라면 {test100 : 1} , {test200 : -1} , {test300 : 1} 처럼 꼬일수있다.

 

따라서 해당 integer끼리 그냥 뺄셈을 이용해주면 차이값을 통해 number끼리 크기 비교가 가능하다.

반응형

'코딩테스트 > Java' 카테고리의 다른 글

[JAVA]백준 치킨배달  (4) 2021.04.12
[JAVA] 백준 N과 M(2), DFS 중복X  (0) 2021.03.31
(2018카카오) 방금그곡 Java  (0) 2021.03.18
(2021카카오) 카드 짝 맞추기 Java  (0) 2021.03.11
(2019카카오) 오픈채팅방 Java  (0) 2021.03.02