본문 바로가기
코딩테스트/programming_JAVA

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

by prometedor 2023. 12. 15.

Arrays.sort 와 compareTo() 활용하기

문자열 내 마음대로 정렬하기 : Level1

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

풀이 코드

import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings, (s1, s2) -> {
            char c1 = s1.charAt(n);
            char c2 = s2.charAt(n);

            if (c1 == c2) {
                return s1.compareTo(s2);
            } else {
                return c1 - c2;
            }
        });

        return strings;
    }
}

 

ㄴ Arrays.sort 를 사용하고, (s1, s2) -> { ... } 람다식을 사용하였다.

ㄴ Arrays.sort 의 첫 번째 인자로 strings 을 넣어주었는데, 이는 정렬하고자 하는 문자열 배열이다.

Arrays.sort 의 두 번째 인자로는 메서드의 비교자(Comparator)를 정의한 람다식을 넣어주었는데, 이 방식을 이용하여 정렬하도록 했다.

ㄴ c1 과 c2 가 같은 경우 compareTo() 메서드를 이용하여 비교를 해주었다. 여기서는 문자열을 비교하는 경우에 해당한다.

 

compareTo()

문자열을 비교하는 경우 (사전순 비교)

  • 0 : 두 문자열이 같은 경우
  • 음수 : 인자가 객체보다 사전적으로 순서가 앞인 경우
  • 양수 : 객체가 인자보다 사전적으로 순서가 앞인 경우

숫자를 비교하는 경우

  • 0 : 두 숫자가 같은 수인 경우
  • 음수 : 인자가 객체보다 큰 수인 경우
  • 양수 : 객체가 인자보다 큰 수인 경우


Arrays.sort 메서드

=> 배열을 정렬하는데 사용되는 메서드로, 여기서는 문자열 배열 strings를 정렬한다. 두 번째 인자로는 비교자(Comparator)가 사용된다.


람다식 (s1, s2) -> { ... }

=> Comparator를 구현하는 함수형 인터페이스를 의미합니다. 여기서 s1과 s2는 두 비교 대상인 문자열을 나타낸다.

char c1 = s1.charAt(n); 
char c2 = s2.charAt(n);

 

 

ㄴ 주어진 인덱스 n에 해당하는 문자를 추출한다.

 

if (c1 == c2) { 
	return s1.compareTo(s2); 
}

 

ㄴ 두 문자가 동일하다면 문자열 자체를 비교하여 정렬하도록 했다. compareTo 메서드는 문자열을 사전순으로 비교한다.

 

else { 
	return c1 - c2; 
}


ㄴ 두 문자가 다르다면 문자의 아스키 코드 값을 비교하여 정렬하도록 한다. 이 부분은 문자의 아스키 코드 값에 따라 정렬된다.

 

람다식을 사용하지 않은 풀이

import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                char c1 = s1.charAt(n);
                char c2 = s2.charAt(n);

                if (c1 == c2) {
                    return s1.compareTo(s2);
                } else {
                    return c1 - c2;
                }
            }
        });

        return strings;
    }
}

 

ㄴ 익명 클래스를 사용하여 Comparator를 직접 정의한 코드다.

 

 

궁금했던 점

여기서 java의 Arrays.sort 메서드는 어떤 정렬을 사용할까?

 

먼저 java.util.Arrays 의 sort 메서드를 살펴보자.

 

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Arrays.html#method-detail

 

Arrays (Java SE 17 & JDK 17)

public class Arrays extends Object This class contains various methods for manipulating arrays (such as sorting and searching). This class also contains a static factory that allows arrays to be viewed as lists. The methods in this class all throw a NullPo

docs.oracle.com

 

ㄴ 자바 Api 에서 볼 수 있듯이 java.util.Arrays 의 sort 메서드는 Dual-Pivot Quicksort 알고리즘을 이용한다.

 

그렇다면 Dual-Pivot Quicksort 란 무엇일까?

 

Dual-Pivot Quicksort 은 피봇 1개를 기준으로 삼아 정렬하는 퀵 정렬에서 나아가 피봇 2개를 기준으로 정렬하는 알고리즘이다.

임의의 피봇 2개를 기준으로 pivot1 보다 작은 부분, pivot1 ~ pivot2 사이의 부분, pivot2 보다 큰 부분으로 나눈 뒤 각 부분을 다시 듀얼 피봇 퀵 정렬 방법으로 정렬한다.
pivot2는 항상 pivot1보다 크도록 설정해야함을 주의한다.

 

https://hello-capo.netlify.app/static/93b940669be887fca4e09c9c50895d75/07a9c/dual-pivot-quicksort.png

 

ㄴ 빨간색으로 표시한 숫자 순서대로 정렬되는 것이다. 

 

 

 

문제점 : 풀이를 검색하여 찾아보았는데, Arrays.sort 의 인자에 놓여진 람다식이 이해가 되지 않았다.

해결 방법 : 자바 API 를 통해 정보를 얻도록 했다. 찾아보다보니 Arrays.sort 메서드의 내장 정렬 방법을 몰랐다는 것을 알 수 있었고, Dual-Pivot Quicksort 라는 알고리즘에 대해 알게 되었다. 람다식은 따로 검색해서 알아보니 Comparator 라는 비교자를 사용한다는 것을 알게되었다.

깨달은 바 : 자바 API 와 구글링을 잘 활용하자.