Language/JAVA

[프로그래머스] 문자열 내 마음대로 정렬하기

paran21 2022. 1. 26. 15:10

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

문자열 배열이 주어지고, 해당 문자열의 특정 인덱스(n)를 기준으로 배열을 정렬하는 문제다.

특정 인덱스의 문자만 추출해서 배열을 정렬하고 나서

1. 이걸 이용해 원래의 배열을 정렬하는 부분

2. 인덱스 문자열이 같을 경우 사전순으로 배열하는 부분

이 어려웠다.

 

1.은 특정 인덱스의 문자를 추출한 배열은 원래 배열의 위치와 동일하기 때문에 이를 활용하기 위해 그대로 두고,

정렬을 위해 clone();으로 복사본을 새로 만들었다.

그래서 정렬된 배열(wordSort)과 원래 배열(word)을 비교하여 정렬 순서대로 해당되는 index를 찾고

이 index에 해당하는 strings값을 answer배열에 하나씩 넣는 방식으로 해결했다.

 

2.는 문자열의 사전적 배열 순서를 비교하여 int값(동일하면 0, 인자가 앞서면 양수, 호출하는 객체가 앞서면 음수)을 반환하는 compareTo를 사용했다.

word배열에서 동일한 값인 경우에 해당 인덱스의 strings 문자열 값을 비교하여 사전순으로 배열되도록 자리를 바꾸었다. 

import java.util.Arrays;

class Solution {
    public String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];
        //비교하려는 index위치의 char을 배열로 선언
        char[] word = new char[strings.length];
        for (int i = 0; i < strings.length; i++) {
            word[i] = String.valueOf(strings[i]).charAt(n);
        }
        //i와 i+1(=j)가 같은 경우 사전순으로 배열되도록 조정
        for (int i = 0; i < strings.length-1; i++) {
            for (int j = i+1; j < strings.length; j++) {
                if (word[i] == word[j]) {
                    //j가 i보다 사전적으로 앞설 때 자리 바꿈
                    if (strings[i].compareTo(strings[j]) > 0) {
                        String temp;
                        temp = strings[i];
                        strings[i] = strings[j];
                        strings[j] = temp;
                    }
                }
            }
        }
        //배열을 위해 복사본을 만들고 정렬
        //원래의 배열은 처음 제시된 strings에서의 위치를 확인하기 위해 유지
        char[] wordSort = word.clone();
        Arrays.sort(wordSort);

        //정렬한 wordSort를 for문으로 돌려서 순서대로 일치하는 인덱스를 찾음
        //해당 인덱스의 strings를 answer에 하나씩 넣음
        for (int i = 0; i < wordSort.length; i++) {
            for (int j = 0; j < wordSort.length; j++) {
                //동일한 문자열을 찾지 않도록 이미 사용한 문자열은 찾을 수 없게 '0'을 할당
                if (wordSort[i] == word[j]) {
                    answer[i] = strings[j];
                    word[j] = '0';
                    break;
                }
            }
        }

        return answer;
    }
}

앞뒤 문자열을 비교할 때 for문을 겹쳐 사용하고

첫번째는 0부터 하나 전까지, 두번째는 i+1부터 끝까지 하는 방식을 다른 답안에서 보았는데 활용하기 좋을 것 같다.

for (int i = 0; i < strings.length-1; i++) {
    for (int j = i+1; j < strings.length; j++)

++다른 답안 중에 해당 인덱스의 글자를 아에 배열의 문자열 앞에 붙여서 정렬하는 방식이 있었다.

이렇게하면 인덱스 글자가 동일해도 사전순 배열이라서 따로 신경쓸 필요가 없다.

그리고 출력할 때는 substring을 사용해서 원래의 문자만 출력한다. 

import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        String[] answer = {};
        ArrayList<String> arr = new ArrayList<>();
        for (int i = 0; i < strings.length; i++) {
            arr.add("" + strings[i].charAt(n) + strings[i]);
        }
        Collections.sort(arr);
        answer = new String[arr.size()];
        for (int i = 0; i < arr.size(); i++) {
            answer[i] = arr.get(i).substring(1, arr.get(i).length());
        }
        return answer;
    }
}