[프로그래머스] 17686. 파일명 정렬

2 분 소요

문제 링크

[프로그래머스] 17686. 파일명 정렬


풀이 과정

정렬 방법은 다음의 순서와 규칙을 따릅니다.

  1. HEAD 를 기준으로 사전 오름차순으로 정렬합니다.
  2. 만약 HEAD 가 같다면, NUMBER 를 숫자 오름차순으로 정렬합니다.
  3. 만약 NUMBER 가 같다면, files 에 입력된 순서를 유지합니다.
  4. TAIL 은 신경쓰지 않습니다.


정렬 함수를 위 규칙대로 구현할 수 있는가를 확인하는 문제입니다.

Java 의 경우, Collections.sort() 메소드를 사용하기 위해 Comparator 객체와 문자열의 사전식 정렬을 위해 compareTo() 메소드를 이용해 정렬 순서를 정했습니다.

Javascript 도 마찬가지로 Array.sort() 함수를 사용을 위해 정렬 방식을 정의하는 compareFunction 과 문자열의 사전식 정렬을 위해 localeCompare() 함수를 사용했습니다.

함수 makeHeadmakeNumber 를 정의해, 각각 HEADNUMBER 를 만들고, 이를 이용해 문제에서 요구하는 규칙에 맞게 양의 정수, 음의 정수, 0 을 반환함으로써 정렬을 완성했습니다.


코드

Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main {
    public static String[] solution(String[] files) {
        String[] answer = new String[files.length];

        ArrayList<File> list = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            list.add(new File(files[i].toUpperCase(), i));
        }

        Comparator comp = new Comparator<File>() {

            @Override
            public int compare(File f1, File f2) {
                StringBuffer f1_head = makeHead(f1);
                StringBuffer f2_head = makeHead(f2);

                int f1_idx = f1_head.length(), f2_idx = f2_head.length();

                if (f1_head.toString().compareTo(f2_head.toString()) > 0) return 1;
                else if (f1_head.toString().compareTo(f2_head.toString()) < 0) return -1;
                else {
                    int f1_number = makeNumber(f1, f1_idx);
                    int f2_number = makeNumber(f2, f2_idx);

                    if (f1_number > f2_number)  return 1;
                    else if (f1_number < f2_number)  return -1;
                    else return 0;
                }
            }
        };

        Collections.sort(list, comp);

        for (int i = 0; i < list.size(); i++) {
            File file = list.get(i);
            answer[i] = files[file.index];
        }

        return answer;
    }

    private static StringBuffer makeHead(File file) {
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < file.fileName.length(); i++) {
            char c = file.fileName.charAt(i);
            if (Character.isDigit(c)) break;
            sb.append(c);
        }

        return sb;
    }

    private static int makeNumber(File file, int index) {
        StringBuffer sb = new StringBuffer();

        while (index < file.fileName.length() && Character.isDigit(file.fileName.charAt(index))) {
            sb.append(file.fileName.charAt(index));
            index++;
        }

        return Integer.parseInt(sb.toString());
    }

    private static class File {
        String fileName;
        int index;

        public File(String fileName, int index) {
            this.fileName = fileName;
            this.index = index;
        }
    }

    public static void main(String[] args) {
        solution(new String[]{"img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"});
//        solution(new String[]{"F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"});
//        solution(new String[]{"img-.0005.png", "im.g-5.png", "img.- 3.jpg", "im.g- 001.png"});
    }
}

Javascript

const solution = (files) => {
    var answer = [];

    let list = [];
    for (let i = 0; i < files.length; i++) {
        list.push(new File(files[i].toUpperCase(), i));
    }

    list.sort(compare);

    for (let i = 0; i < list.length; i++) {
        answer.push(files[list[i].index]);
    }

    return answer;
};

const compare = (f1, f2) => {
    let f1_head = makeHead(f1);
    let f2_head = makeHead(f2);

    let f1_idx = f1_head.length,
        f2_idx = f2_head.length;

    if (f1_head.localeCompare(f2_head) > 0) return 1;
    else if (f1_head.localeCompare(f2_head) < 0) return -1;
    else {
        let f1_number = makeNumber(f1, f1_idx);
        let f2_number = makeNumber(f2, f2_idx);

        if (f1_number > f2_number) return 1;
        else if (f1_number < f2_number) return -1;
        else return 0;
    }
};

const makeHead = (file) => {
    let ret = "";

    for (let i = 0; i < file.fileName.length; i++) {
        let ch = file.fileName.charAt(i);
        if (!isNaN(parseInt(ch))) break;
        ret = ret.concat(ch);
    }

    return ret;
};

const makeNumber = (file, index) => {
    let ret = "";

    while (index < file.fileName.length && !isNaN(file.fileName.charAt(index))) {
        ret = ret.concat(file.fileName.charAt(index));
        index++;
    }

    return parseInt(ret);
};

class File {
    constructor(fileName, index) {
        this.fileName = fileName;
        this.index = index;
    }
}

solution(["img12.png", "img10.png", "img02.png", "img1.png", "IMG01.GIF", "img2.JPG"]);
// solution(["F-5 Freedom Fighter", "B-50 Superfortress", "A-10 Thunderbolt II", "F-14 Tomcat"]);
// solution(["img-.0005.png", "im.g-5.png", "img.- 3.jpg", "im.g- 001.png"]);

카테고리:

업데이트:

댓글남기기