본문 바로가기
Preparing Coding Test/Programmers L1

[Java] 문자열 내림차순으로 배치하기

by weero 2020. 7. 17.

문제

https://programmers.co.kr/learn/courses/30/lessons/12917

 

코딩테스트 연습 - 문자열 내림차순으로 배치하기

문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요. s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 �

programmers.co.kr

 

 

참고

1. java.lang 패키지

- 별도로 import를 해주지 않아도 사용할 수 있는 class들

- StringBuilder      vs. StringBuffer, String

   - 모두 문자열을 저장, 관리

 

1-1. String

- 불변(immutuable)

   - String은 final형

   - String 객체는 한번 생성되면 할당된 메모리 공간이 변하지 않는다.

   - 새로운 값을 할당할 때마다 새로 생성된다.

      - + 연산자, concat 메서드 사용 → 새로운 String 객체를 만든 후, 새 String 객체에 연결된 문자열을 저장하고 그 객체를 참조

      - 각 String의 주소값이 Stack에 쌓이고, 클래스 객체들은 Heap에 쌓이게 된다.

         - 기존 객체가 제거되면 Garbage Collection이 회수

         - Garbage Collection은 Heap 메모리 영역에서 동작

   - 문자열 연산이 많은 경우, 성능이 좋지 않음

 

1-2. StringBuffer

- java.lang.Object

   - java.lang.StringBuffer

- StringBuffer는 값이 변할 수 있다.(mutuable)

   - 기존 버퍼 크기를 늘리며 유연하게 동작한다.

- 값을 memory에 append하는 방식으로 클래스를 직접 생성하지 않는다.

   - 클래스가 생성될 때 method들과 variable도 같이 생성되는데, StringBuffer는 이런 시간을 사용하지 않는다.

- 각 메서드별로 Synchronized Keyword가 존재하여, multiple thread 환경에서도 동기화 가능

 

1-3. StringBuilder

- java.lang.Object

   - java.lang.StringBuilder

- StringBuilder는 값이 변한다.(mutuable)

   - 기존 버퍼 크기를 늘리며 유연하게 동작한다.

- 동기화를 보장하지 않는다. (단일스레드 환경)

 

==> 결론

String은 짧은 문자열을 더할 경우 사용

StringBuffer는 스레드에 안전한 프로그램 필요 시 or 스레드에 안전한지 모를 때

StringBuilder는 스레드에 안전한지 여부가 전혀 관련 없을 때

성능 : StringBuilder > StringBuffer >>> String

 

2. java.lang.String.toCharArray()

- public char[] String.toCharArray()

- 문자열을 char형 배열로 변환

 

3. StringBuilder.reverse()

- 문자들의 순서를 반대로 뒤집는다.

 

4. Char 배열을 String으로 변환하는 방법

 

4-1. String 생성자

char 배열을 String 생성자의 인자에 넣고 String을 생성한다.

char[] charArray = {'a', 'b', 'c', 'd'};
String str = new String(charArray);
System.out.println(str); //abcd

 

4-2. String.valueOf()

char[] charArray = {'a', 'b', 'c', 'd'};
String str = String.valueOf(charArray);
System.out.println(str); //abcd

 

4-3. StringBuilder

char[] charArray = {'a', 'b', 'c', 'd'};
StringBuilder sb = new StringBuilder();

//char Array --> StringBuilder
for(char ch : charArray){
	sb.append(ch);
}

//String --> StringBuilder
String str = sb.toString();

System.out.println(str); //abcd

 

4-4. Stream

Stream으로 char를 String으로 변환하고, String들을 합쳐 하나의 String으로 만든다.

char[] charArray = {'a', 'b', 'c', 'd'};
Stream<Character> charStream = Arrays.stream(charArray);
String str = charStream.map(String::valueOf).collect(Collectors.joining());
System.out.println(str); //abcd

 

 

풀이

1. String을 char[] 캐릭터형 배열로 변환

   String을 정렬하고 뒤집기 위함이다.

 

2. 배열을 sort

   reverse()는 순서를 뒤집지 내림차순으로 정렬해주지 않는다.

   먼저 오름차순으로 바꾸어준다.

 

3. 정렬한 배열을 뒤집어 return

   1) 배열을 List를 활용해 reverse를 하는 방법과

   2) StringBuilder를 이용하는 방법이 있다.

   2)가 더 효율적

 

   오름차순으로 정렬된 char array를 String으로 바꾸고 : new String(sArr)

   뒤집는 메서드가 있는 StringBuilder에 넣어 뒤집고 : new StringBuilder(~~).reverse()

   반환해야 하는 자료형인 String으로 바꾸어 줬다 : .toString();

 

 

코드

import java.lang.StringBuilder;
import java.util.Arrays;
class Solution {
    public String solution(String s) {
        char[] sArr = s.toCharArray();
        Arrays.sort(sArr);
        return new StringBuilder(new String(sArr)).reverse().toString();
    }
}