정수 내림차순으로 배치하기 (자바)

김재현·5일 전
0

알고리즘 풀이

목록 보기
90/90
post-thumbnail

1. 문제

2. 정답 풀이

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

class Solution {
    public long solution(long n) {
        
        StringBuilder strBuilder = new StringBuilder();
        
        Arrays.stream(String.valueOf(n).split(""))
        .map(a -> Long.parseLong(a))
        .sorted(Comparator.reverseOrder())
        .collect(Collectors.toList())
        .forEach(a -> strBuilder.append(a));
        
        return Long.parseLong(strBuilder.toString());
        
    }
}
  1. split()에 의해 만들어진 list를 stream으로 처리하기 위해 Arrays.stream()
  2. 각각을 Long으로 치환하며 Comparator.reverseOrder()를 사용해 내림차순 정렬(역정렬)
  3. toList()를 사용하려 했으나 자바 버전때문에 불가(Java 16 이상) -> collect(Collector.toList())List로 전환 (Java 8 이상)
  4. StringBuilder를 사용해서 문자열 생성

2-1. Collect 메서드란?

Stream API에서 최종 연산(terminal operation)을 수행하는 메서드. 스트림의 결과를 컬렉션(리스트, 맵 등)이나 다른 형태로 변환하는 역할을 한다.

<R, A> R collect(Collector<? super T, A, R> collector);

  • T: 스트림의 요소 타입
  • A: 집합에 사용되는 중간 결과 타입 (예: ArrayList나 StringBuilder 등)
  • R: 최종 결과 타입 (예: List, Set, Map 등)

Comparator의 Map 변환 사용 예시

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "orange");

        // 스트림을 Map으로 수집 (문자열 길이를 키로 사용)
        Map<Integer, String> result 
        	= list.stream()
        		.collect(Collectors.toMap(String::length, s -> s));

        System.out.println(result);  // {5=apple, 6=banana, 6=orange}
    }
}
  • String::length : 메서드 참조(String 클래스의 length() 메서드를 직접 참조)

2-2. Comparator란?

Comparator.reverseOrder()의 사용 예시

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(5, 2, 8, 1, 3);

        list.sort(Comparator.reverseOrder());

        System.out.println(list);
    }
}

2-3. StringBuilder 의 메서드

문자열 추가 (append, insert)

  • append(String str): 문자열을 StringBuilder의 끝에 추가
  • insert(int offset, String str): 지정된 위치(offset)에 문자열을 삽입

문자열 삭제 (delete, deleteCharAt, replace)

  • delete(int start, int end): start부터 end까지의 문자를 삭제
  • deleteCharAt(int index): 지정된 인덱스의 문자를 삭제
  • replace(int start, int end, String str): start부터 end까지의 문자를 str로 대체

문자열 길이 및 용량 관련 메서드

  • length()
  • capacity() : 현재 StringBuilder의 용량을 반환
  • trimToSize(): StringBuilder의 용량을 현재 문자열의 길이에 맞게 줄임

문자열 뒤집기 (reverse)

  • reverse()

문자열 검색 (indexOf, lastIndexOf)

  • indexOf(String str): 문자열에서 str이 처음 등장하는 인덱스를 반환
  • lastIndexOf(String str): 문자열에서 str이 마지막으로 등장하는 인덱스를 반환

부분 문자열 추출 (substring)

  • substring(int start): start 인덱스부터 끝까지의 부분 문자열을 반환
  • substring(int start, int end): start부터 end까지의 부분 문자열을 반환

변경 가능 문자열로 변환 (toString)

  • toString(): StringBuilder 객체를 String 객체로 변환

반복문 사용 (setCharAt, getChars)

  • setCharAt(int index, char ch): 지정된 인덱스의 문자를 ch로 변경
  • getChars(int srcBegin, int srcEnd, char[ ] dst, int dstBegin): StringBuilder의 문자열을 char 배열로 복사

3. 다른 사람 풀이

3-1. 가독성 향상

import java.util.*;

class Solution {
  public long solution(long n) {
        String[] list = String.valueOf(n).split("");
        Arrays.sort(list);

        StringBuilder sb = new StringBuilder();
        for (String aList : list) sb.append(aList);

        return Long.parseLong(sb.reverse().toString());
  }
}

StringBuilderreverse()를 사용하여 String으로 만들었다.
그 덕분에 코드가 전체적으로 깔끔하고 가독성이 좋다.

이번에 StringBuilder에 대해 학습했으니 collect의 대체로 사용해봐도 좋을 것 같다.

3-2. Chars(), 옛코드

public class ReverseInt {
    String res = "";
    public int reverseInt(int n){
        res = "";
        Integer.toString(n).chars().sorted().forEach(c -> res = Character.valueOf((char)c) + res);
        return Integer.parseInt(res);
    }

    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void  main(String[] args){
        ReverseInt ri = new ReverseInt();
        System.out.println(ri.reverseInt(118372));
    }
}
  • chars(): 문자열을 IntStream으로 변환
  • forEach(c -> res = Character.valueOf((char)c) + res)
    :정렬된 각 문자를 하나씩 처리하면서 res에 문자를 앞에 추가

하지만 이 코드는 지금은 작동이 안될 것이다.
왜냐하면 stream에는 final 변수만 들어갈 수 있고, 이것을 변경하려고하면 컴파일 에러가 발생할 것이다.

이 코드를 수정한다면 res 가 StringBuilder 의 객체가 된다면 사용 할 수 있다.

profile
I live in Seoul, Korea, Handsome

0개의 댓글