Skip to main content

19. [Java] 접미사 배열

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

  • 입력값: 문자열 my_string (예: "banana")
  • 접미사란: 문자열의 특정 인덱스부터 끝까지 잘라낸 부분 문자열
    • 예: "banana"의 접미사 → "banana", "anana", "nana", "ana", "na", "a"
  • my_string의 모든 접미사를 구한 뒤
  • 사전순(lexicographical order) 으로 정렬
  • 결과를 String[] 배열로 반환
    • 예: 입력 "banana" → 출력 ["a", "ana", "anana", "banana", "na", "nana"]

  • my_string은 알파벳 소문자로만 이루어져 있다.
  • 1 ≤ my_string의 길이 ≤ 100

정답코드

  1. ​StringBuilder 생성해서 문자열 누적 (이어붙이기 문제)
  2. 모든 문자열 배열 my_strings에 대해 반복문을 수행하면서, parts[i]에 지정된 시작-끝 인덱스를 기반으로 각 문자열에서 부분 문자열을 추출한다.
    • s = parts[i][0], e = parts[i][1]
    • substring(s, e + 1)을 통해 s부터 e까지 포함하는 문자열을 추출한다.
  3. 각 단계에서 잘라낸 문자열을 StringBuilder계속 덧붙이기
  4. 모든 부분 문자열을 누적한 후, 최종적으로 StringBuilder를 문자열로 변환하여 반환한다.
    • 즉, 모든 parts[i]에 해당하는 부분 문자열들을 순서대로 이어붙인 결과 문자열이 리턴된다.
import java.util.*;

class Solution {
    public String[] solution(String my_string) {
        ArrayList<String> answer = new ArrayList<>();
        
        for (int i = 0; i < my_string.length(); i++) {
            answer.add(my_string.substring(i));
        }
        // 사전순 정렬
        Collections.sort(answer);

        // ArrayList<String> → String[] 변환
        return answer.toArray(new String[0]);
    }
}

​ArrayList 오름차순 정렬

Collections.sort(list);
// 사전순 정렬
Collections.sort(answer);

ArrayList 는 배열이 아니라 Collections 이기 때문에 정렬할 때 Collections.sort()를 쓴다.
또는 answer.sort(Comparator.naturalOrder()); 또는 람다식으로 아래와 같이 작성해도 된다.

answer.sort((a, b) -> a.compareTo(b));

하지만 이 문제처럼 단순 오름차순 정렬일 때는 Collections.sort()와 결과가 같기 때문에 람다식을 사용하는 실익이 없다.


객체를 선언하지 않고 return 문에서 바로 ArrayList<String> → String[] 변환하는 법

return answer.toArray(new String[0]);
return answer.toArray(new String[0]);
  • 가변 리스트 ArrayList<String> → 배열 String[] 으로 변환 시
  • 별도 변수나 객체 생성 없이, return문에서 바로 변환 가능
  • new String[0]은 타입 명시용이며, 내부적으로 적절한 크기의 배열로 자동 처리된다.

Stream을 써서 해결한 코드

for문 없이 stream으로 접미사 수집 + 정렬 + 배열 변환이 가능하다. 전체 코드를 완전히 Stream 기반으로 바꾸면 아래와 같다.

import java.util.*;
import java.util.stream.*;

class Solution {
    public String[] solution(String my_string) {
        return IntStream.range(0, my_string.length())   // 0부터 문자열 길이-1까지
                .mapToObj(i -> my_string.substring(i)) // 접미사 생성
                .sorted()                               // 사전순 정렬
                .toArray(String[]::new);                // String[]로 변환
    }
}

List를 int[]로 변경할 때는?

List<Integer>int[]로 변환할 때는 스트림(Stream)을 활용해야 한다. 기본형 int는 제네릭으로 직접 다룰 수 없기 때문에 다음처럼 변환한다.

List<Integer> → int[] 변환

List<Integer> list = Arrays.asList(1, 2, 3, 4);

// 변환
int[] arr = list.stream()
                .mapToInt(Integer::intValue)
                .toArray();
  • list.stream() → 스트림 생성
  • mapToInt(Integer::intValue) → Integer를 기본형 int로 변환
  • toArray()int[] 배열로 변환

반대로 int[]List<Integer>로 바꾸려면?

int[] arr = {1, 2, 3};
List<Integer> list = Arrays.stream(arr)
                           .boxed()
                           .collect(Collectors.toList());