[Java] programmers lv 1. 정수 내림차순으로 배치하기

Eunbi Lee·2023년 6월 7일
1

Algorithm

목록 보기
4/7
post-thumbnail

개인적으로 저는 글을 쓸 때, 많은 정보로 인해 제가 전달하고자 하는 본론이 흐려질 수 있기 때문에 너무 많은 정보가 담기지 않도록 조심하는 편입니다.

예시로 Alogrithm 카테고리의 글들은 level 1의 특성상, 자바의 기본 문법 및 메소드를 활용한 풀이를 위주로 소개해드리고 싶었습니다.

그런데 이번 문제는 개편된 문제이기 때문에, 최근 풀이들만 들고 오다보니 Stream에 대해서 벌써 다루게 되었네요. 따라서 Stream에 대해 설명하다보니 글이 좀 길어졌습니다 😅

정수 내림차순으로 배치하기

문제 설명

함수 solution은 정수 n을 매개변수로 입력받습니다. n의 각 자릿수를 큰것부터 작은 순으로 정렬한 새로운 정수를 리턴해주세요. 예를들어 n이 118372면 873211을 리턴하면 됩니다.

제한 조건

n은 1이상 8000000000 이하인 자연수입니다.

입출력 예

n = 118372 / return 873211

풀이 1

// n = 118372
import java.util.*;

class Solution {
  public long solution(long n) {
  	  // ["1", "1", "8", "3", "7", "2"]
  	  String[] list = String.valueOf(n).split("");
      // ["1", "1", "2", "3", "7", "8"]
      Arrays.sort(list);
      
      // 112378
      StringBuilder sb = new StringBuilder();
      for (String aList : list) sb.append(aList);
    
      // 873211
      return Long.parseLong(sb.reverse().toString());
  }
}

💡 핵심 메소드 정리

(1) String[] list = String.valueOf(n).split("");

주어진 int n (여기선 118372)을 String으로 변환 후 공백과 쉼표를 기준으로 분리하여 배열에 저장한다.

(2) Arrays.sort(list);

String 배열 list를 오름차순으로 정렬한다.

(3) for (String aList : list) sb.append(aList);

주어진 컬렉션 또는 배열의 각 원소에 대해 순차적으로 접근하고, 이어붙이는 반복 작업을 수행한다.

즉, 과정을 풀어보면 다음과 같습니다.

1) 1
2) 11
3) 112
4) 1123
5) 11237
6) 112378

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

1) StringBuilder 객체에 대해 뒤집는 연산을 수행한 후 2) String 객체로 변환한다.
그리고 3) long type으로 파싱한 후 반환한다.

즉, 과정은 다음과 같습니다.

1) 112378 → 873211
2) (StringBuilder) 873211 → (String) 873211
3) (String) 873211 → (long) 873211

풀이 2

import java.util.*;

class Solution {
    public long solution(long n) {
    	return Long.parseLong(String.valueOf(n).chars().mapToObj(ch -> (char) ch)
                .sorted(Comparator.reverseOrder())
                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
                .toString());
    }
}

💡 핵심 메소드 정리

(1) 1) String.valueOf(n) 2).chars() 3).mapToObj(ch -> (char) ch)

1) 주어진 정수 n을 String으로 변환한다, 2) 문자열의 각 문자를 Unicode 값을 원소로 갖는 원시 타입 IntStream으로 변환한다. 3) IntStream을 각 원소로 해당하는 char로 변환한 Stream<Character>으로 변환한다.

String.chars() : String의 각 문자에 해당하는 int 값을 반환하는 IntStream을 반환
IntStream.mapToObj() : IntStream의 각 원소에 대해 주어진 함수를 적용하여 결과를 Object(객체)로 변환하는 Stream을 반환

(2) .sorted(Comparator.reverseOrder())

Stream<Character> 객체를 내림차순으로 정렬한다.

Stream.sorted() : 원소들로 구성된 Stream을 정렬된 순서로 반환

(3) .collect( 1) StringBuilder::new, 2) StringBuilder::appendCodePoint, 3) StringBuilder::append)

Stream.collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) : 이 Stream의 요소에 대해 변경 가능한 축소 작업을 수행

1) StringBuilder 객체를 생성한다. 2) StringBuilder에 해당 ASCII Code의 character를 추가한다. 3) 그리고 StringBuilder 뒤에 추가한다.

StringBuilder.appendCodePoint() : 해당 ASCII Code의 character을 추가
StringBuilder.append() : 추가 및 연결

(4) .toString()

String으로 변환한다.

(5) Long.parseLong()

Long으로 변환한다.

풀이 3

import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;

class Solution {
    public long solution(long n) {
        Integer[] arr = Stream.of(String.valueOf(n).split(""))
            .map(Integer::valueOf)
            .toArray(Integer[]::new);
        
        Arrays.sort(arr, Collections.reverseOrder());
        
        StringBuilder sb = new StringBuilder();
        for (int num : arr) {
            sb.append(num);
        }
        
        long answer = Long.parseLong(sb.toString());
        return answer;
    }
}

💡 핵심 메소드 정리

(1) Stream.of(String.valueOf(n).split(""))

주어진 정수 n을 String으로 변환 후, Stream<String>을 생성한다.

Stream.of() : variable parameter를 전달받아 Stream 생성

(2) .map(Integer::valueOf)

Stream의 각 원소들을 Integer 타입으로 파싱하여 Stream<Integer>으로 변환된다.

Stream.map( -> 또는 :: ) : Stream의 각 원소들이 기호(-> 또는 ::)를 기준으로 오른쪽에 위치한 메소드를 수행
Stream.map(Integer::valueOf)의 경우, valueOf에 대하여 Integer 파싱을 수행하는 Integer::valueOf 함수를 인자로 받음

✏️ 즉, Stream.map() 메소드 내에서 사용되는 함수에 따라 변환되는 방향이 달라질 수 있습니다.

(3) .toArray(Integer[]::new)

Stream<Integer>의 각 원소들을 담을 수 있는 Integer Array를 생성한다.

Stream.toArray() : Stream의 원소들을 포함하는 배열을 반환

Reference

(1) Oracle 공식 문서
https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#mapToObj-java.util.function.IntFunction-

(2) Stream ::
https://wakestand.tistory.com/646

(3) Stream - MapToObj
https://velog.io/@zion9948/Stream%EC%97%90%EC%84%9C-MapToObj-%EB%9E%80
https://isntyet.github.io/java/java-stream-%EC%A0%95%EB%A6%AC(sort)/
https://codechacha.com/ko/java-convert-string-to-chararray/

(4) Stream
https://juno-juno.tistory.com/50
http://www.tcpschool.com/java/java_stream_creation
https://dpdpwl.tistory.com/81

(5) StringBuilder
https://mebadong.tistory.com/13

(6) char
https://kang-james.tistory.com/entry/JAVA-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-%EB%AC%B8%EC%9E%90-%ED%83%80%EC%9E%85-char-%EC%99%80-%EB%AC%B8%EC%9E%90%EC%97%B4-String-%EC%9D%98-%EC%A7%84%EC%8B%A4

추후, Stream에 대해서 블로그에 정리해보도록 하겠습니다. 🍰

profile
B - B = 이은비

0개의 댓글