[프로그래머스 Level.2] 파일명 정렬 - 정규표현식, 정렬

오형상·2024년 7월 22일
0

알고리즘

목록 보기
22/23
post-thumbnail

문제 - 파일명 정렬

소스코드

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

/**
 * 프로그래머스 Level.2 파일명 정렬
 * https://school.programmers.co.kr/learn/courses/30/lessons/17686
 **/
class Solution {
    // 정규 표현식을 컴파일하여 패턴 객체를 생성합니다.
    // (\\D+): 숫자가 아닌 문자열 부분을 매칭합니다.
    // (\\d{1,5}): 최대 5자리의 숫자 부분을 매칭합니다.
    private final Pattern pattern = Pattern.compile("(\\D+)(\\d{1,5})");

    public String[] solution(String[] files) {
        // 파일 배열을 정렬합니다. 정렬 기준은 Comparator를 사용하여 정의합니다.
        Arrays.sort(files, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 각 파일 이름에 대해 Matcher 객체를 생성합니다.
                Matcher matcher1 = pattern.matcher(o1);
                Matcher matcher2 = pattern.matcher(o2);

                // 정규 표현식 패턴과 매칭되는 경우에만 비교를 수행합니다.
                if (matcher1.find() && matcher2.find()) {
                    // 첫 번째 매칭 그룹(문자열 부분)을 대문자로 변환하여 비교합니다.
                    String head1 = matcher1.group(1).toUpperCase();
                    String head2 = matcher2.group(1).toUpperCase();

                    // 두 번째 매칭 그룹(숫자 부분)을 정수로 변환하여 비교합니다.
                    int number1 = Integer.parseInt(matcher1.group(2));
                    int number2 = Integer.parseInt(matcher2.group(2));

                    // head 부분을 비교합니다.
                    int headCompare = head1.compareTo(head2);

                    // head가 같으면 number를 비교하여 정렬합니다.
                    if (headCompare == 0) {
                        return Integer.compare(number1, number2);
                    }

                    // head가 다르면 head를 기준으로 정렬합니다.
                    return headCompare;
                }
                // 정규 표현식에 매칭되지 않으면 원래 문자열을 비교하여 정렬합니다.
                return o1.compareTo(o2);
            }
        });

        // 정렬된 파일 배열을 반환합니다.
        return files;
    }

    public static void main(String[] args) {
        Solution s = new Solution();

        // 예제 테스트 케이스 1: 파일 이름들을 정렬하여 출력합니다.
        System.out.println(Arrays.toString(
                s.solution(new String[]{"img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"})));

        // 예제 테스트 케이스 2: 파일 이름들을 정렬하여 출력합니다.
        System.out.println(Arrays.toString(
                s.solution(new String[]{"F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II",
                        "F-14 Tomcat"})));
    }
}

자바 정규표현식

자바의 정규표현식(Regular Expression)은 문자열의 패턴을 정의하고, 이를 통해 문자열 검색, 추출, 치환 등의 작업을 효율적으로 수행할 수 있게 해주는 강력한 도구입니다. 자바에서는 java.util.regex 패키지를 통해 정규표현식을 지원합니다. 이 블로그 포스트에서는 자바 정규표현식의 기본 개념과 활용 방법에 대해 자세히 설명하겠습니다.

1. 정규표현식 기본 개념

정규표현식은 특정 패턴을 정의하는 문자열입니다. 이를 통해 문자열 내에서 특정 패턴을 찾거나, 추출하거나, 치환할 수 있습니다. 자바에서는 Pattern 클래스와 Matcher 클래스를 사용하여 정규표현식을 처리합니다.

주요 클래스

  • Pattern 클래스: 정규표현식을 정의하고 컴파일하는 클래스입니다.
  • Matcher 클래스: 컴파일된 정규표현식을 사용하여 문자열을 매칭하는 클래스입니다.

2. Pattern 클래스

Pattern 클래스는 정규표현식을 정의하고 컴파일하는 데 사용됩니다. 주요 메서드는 다음과 같습니다:

  • compile(String regex): 주어진 정규표현식을 컴파일하여 Pattern 객체를 반환합니다.
  • compile(String regex, int flags): 플래그와 함께 정규표현식을 컴파일합니다.
Pattern pattern = Pattern.compile("\\d+");

3. Matcher 클래스

Matcher 클래스는 Pattern 객체와 매칭할 문자열을 사용하여 생성됩니다. 주요 메서드는 다음과 같습니다:

  • matches(): 문자열 전체가 패턴과 일치하는지 확인합니다.
  • find(): 패턴이 문자열 내에서 일치하는 부분을 찾습니다.
  • group(): 매칭된 부분 문자열을 반환합니다.
  • replaceAll(String replacement): 패턴에 일치하는 모든 부분을 주어진 문자열로 치환합니다.
Matcher matcher = pattern.matcher("123abc");
if (matcher.find()) {
    System.out.println("Found: " + matcher.group());
}

4. 정규표현식의 기본 문법

문자 클래스

  • [abc]: 'a', 'b', 'c' 중 하나와 일치
  • [^abc]: 'a', 'b', 'c'가 아닌 문자와 일치
  • [a-z]: 'a'부터 'z'까지의 문자와 일치

미리 정의된 문자 클래스

  • .: 임의의 한 문자
  • \d: 숫자 (0-9)
  • \D: 숫자가 아닌 문자
  • \w: 단어 문자 (알파벳, 숫자, 밑줄)
  • \W: 단어 문자가 아닌 문자
  • \s: 공백 문자 (스페이스, 탭 등)
  • \S: 공백 문자가 아닌 문자

경계 매칭

  • ^: 문자열의 시작
  • $: 문자열의 끝
  • \b: 단어 경계
  • \B: 단어 경계가 아님

반복

  • *: 0회 이상 반복
  • +: 1회 이상 반복
  • ?: 0회 또는 1회
  • {n}: 정확히 n회 반복
  • {n,}: n회 이상 반복
  • {n,m}: n회 이상, m회 이하 반복

0개의 댓글