본문 바로가기

코딩 테스트

[프로그래머스] (Lv.1) 문자열 내 마음대로 정렬하기 **

728x90

문제


문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.

 

 <  제한 조건  >

 

  • strings는 길이 1 이상, 50이하인 배열입니다.
  • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
  • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
  • 모든 strings의 원소의 길이는 n보다 큽니다.
  • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.

 

-  출력 예시  -

정답 코드


<  내 정답 코드  >

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings, new Comparator<String>() {  // Comparator 인터페이스 구현
            @Override
            public int compare(String str1, String str2) {  // compare() 메서드 오버라이딩
                if (str1.charAt(n) < str2.charAt(n)) {  // 전달받은 인덱스의 요소를 비교함
                    return -1;
                } else if (str1.charAt(n) > str2.charAt(n)) {
                    return 1;
                } else {    // 만약 비교 문자가 동일하다면, 해당 문자의 앞에서부터 다시 비교
                    for (int i = 0; i < str1.length(); i++) {
                        if (str1.charAt(i) < str2.charAt(i)) {
                            return -1;
                        } else if (str1.charAt(i) > str2.charAt(i)) {
                            return 1;
                        }
                    }
                }
                return 0;
            }
        });
        return strings;
    }
}

 

<  타인 답변 코드  1  >

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings, new Comparator<String>() {
            @Override
            public int compare(String str1, String str2) {
                if (str1.charAt(n) < str2.charAt(n)) {
                    return -1;
                } else if (str1.charAt(n) > str2.charAt(n)) {
                    return 1;
                } else {
                    return str1.compareTo(str2);   //  String의 compareTo() 메서드를 사용!
                }
            }
        });
        return strings;
    }
}

 

<  타인 답변 코드  2  >

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;
    }
}

이것을 주의하자!


-  내가 푼 방법은 Arrays.sort( ) 메서드이다. 정렬하려는 대상이 String 문자열이고, 이미 String 문자열은 Comparable 인터페이스의 compareTo( ) 메서드를 오버라이딩 해서 기본 오름차순으로 설정되어 있다. 따라서 해당 문자열 배열을 단순히 Arrays.sort( ) 해버리면 맨 앞의 String 요소를 기준으로 오름차순한다.

 

해당 문제처럼 정렬 기준을 바꾸기 위해선 Arrays.sort( ) 메서드의 매개변수에 따로 비교 기준을 정의해줘야 한다. 이때 Comparator 인터페이스의 compare( ) 메서드를 구현해 준다. 전달 받은 인덱스 n 을 이용하여 charAt( ) 메서드로 두 단어를 비교하고 -1  ,  1  을 반환한다.

 

만약에 두 문자가 동일하다면, 내부에 for 문을 넣고 해당 문자열의 첫 인덱스부터 하나씩 비교한다. 제한 조건의 "인덱스의 문자가 동일할 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다"를 충족시키기 위한 것이다.

 

-  타인 답변 코드 1을 보면 나와 동일한 알고리즘을 사용했다. 하지만 나보다 좋은 점이 '동일한 문자일 경우'일 때 있다. 나는 코드를 새롭게 만들었는 반면, 타인 답변 코드 1에선 String 객체가 이미 가지고 있는 compareTo( ) 메서드를 사용했다. 생각해보면 어짜피 맨 앞에서부터 사전 순으로 비교할 거니깐 compareTo( ) 메서드를 사용해도 괜찮다..!

 

-  타인 답변 코드 2는 발상의 전환이 놀랍다. 먼저 String 배열을 ArrayList<String>에 저장하는데 이때 비교하려는 단어를 단어 맨 앞에 붙인다. 그리곤 정렬을 한다. 이후 새로운 배열에 넣을 때 비교 대상으로 사용한 단어를 제외한다. 정렬이라고 해도 다양한 방법이 가능하다. 이런 창의적인 방법은 배워야겠다.