[Java - String] 1. 중복 문자 제거하기

2023. 3. 8. 20:36Java/coding test

반응형

주어진 문자열에서, 중복된 문자는 제거하는 코드를 작성하라

  • apple -> aple
  • banana -> ban

  1. 풀이
    1. indexOf 활용
    2. HashSet 활용
    3. stream의 distinct 활용
  2. 성능

1. 풀이

1.1. indexOf 활용

문자열 s의 각 문자를 순회하며
StringBuilder sb에 아직 입력되지 않은 문자를 추가한다.

문자가 sb에 포함되어있지 않다면 추가
포함되어있다면 추가하지 않으면 된다.

static String removeDuplicates1(String s) {
    if (s == null || s.isBlank()) {
        return s;
    }
    StringBuilder sb = new StringBuilder();
    for (char c : s.toCharArray()) {
        if (sb.indexOf(String.valueOf(c)) == -1) {
            sb.append(c);
        }
    }
    return sb.toString();
}

1.2. HashSet 활용

문자열 s에 들어있는 문자를 순회하면서
문자를 HashSet에 추가하는데

HashSet에 포함되어있지 않을 경우 sb에 추가하고
포함되어있을 경우 sb에 추가하지 않습니다.

Set의 add함수는 만일 기존에 값이 들어있을 경우 false, 없을 경우 true를 리턴합니다.

static String removeDuplicates2(String s) {
    if (s == null || s.isBlank()) {
        return s;
    }
    StringBuilder sb = new StringBuilder();
    Set<Character> set = new HashSet<>();
    for (char c : s.toCharArray()) {
        if (set.add(c)) {
            sb.append(c);
        }
    }
    return sb.toString();
}

1.3. stream의 distinct 활용

stream()의 distinct()를 이용하여 중복 문자를 제거하고,
제거한 후 collect(Collectors.joining())으로 리스트를 합치는 방법을 이용할 수 도 있습니다.

static String removeDuplicates3(String s) {
    if (s == null || s.isBlank()) {
        return s;
    }
    return Arrays.asList(s.split("")).stream()
            .distinct()
            .collect(Collectors.joining());
}

2. 성능

다만, 위의 3가지의 방법은 속도 차이가 있습니다.

String s = "aB 8 b tT ! k 2 098!";

라는 문자열에 대해서 아래와 같은 퍼포먼스를 보여줍니다.

실행시간: 80251 ns (0 ms)
aB 8btT!k209

실행시간: 75711 ns (0 ms)
aB 8btT!k209

실행시간: 5073320 ns (5 ms)
aB 8btT!k209

Set을 활용하는 방법이 가장 성능이 빠르고,
거의 비등한 방식으로 indexOf 방식으로 빠르지만
stream()을 활용한 방식은 현저히 느립니다.

이 부분에 대해 고려를 하고 코드를 작성하는 것이 좋을것으로 보입니다.


++

  • RemoveDuplicateCharacters
728x90
반응형