본문 바로가기

프로그래머스 코딩(자바)/Level 0

Programmers Level 0 - 한 번만 등장한 문자

728x90

문제 설명

문자열 s가 매개변수로 주어집니다. s에서 한 번만 등장하는 문자를 사전 순으로 정렬한 문자열을 return 하도록 solution 함수를 완성해보세요. 한 번만 등장하는 문자가 없을 경우 빈 문자열을 return 합니다.

 
제한사항
  • 0 <  s의 길이 < 1,000
  • s는 소문자로만 이루어져 있습니다.

 

 

입출력 예

s result
"abcabcadc" "d"
"abdc" "abcd"
"hello" "eho"

입출력 예 설명

입출력 예 #1

  • "abcabcadc"에서 하나만 등장하는 문자는 "d"입니다.

입출력 예 #2

  • "abdc"에서 모든 문자가 한 번씩 등장하므로 사전 순으로 정렬한 "abcd"를 return 합니다.

입출력 예 #3

  • "hello"에서 한 번씩 등장한 문자는 "heo"이고 이를 사전 순으로 정렬한 "eho"를 return 합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
    public String solution(String s) {
        String answer = "";
        int ar[] = new int[26];
        for(char ch : s.toCharArray()) {
            ar[ch-'a']++;
        }
        for(int i=0;i<ar.length;i++) {
            if(ar[i]==1) answer += (char)('a'+i);
        }
        return answer;
    }
}
cs

 

  반복문을 이용하여  모든 알파벹 소문자의 나타난 개수를 모두 구한다.
   
   int ar[] = new int[26];
   for(char ch : s.toCharArray()) {
         ar[ch-'a']++;
   }
  
  나타난 숫자가 1일때만 문자열에 더해준다.
 
   for(int i=0;i<ar.length;i++) {
         if(ar[i]==1) answer += (char)('a'+i);
   }

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
class Solution {
    public String solution(String s) {
         String answer = "";
         Map<String, List<String>> map = Arrays
                                         .stream(s.split(""))
                                         .collect(Collectors.groupingBy(s1 -> s1));
         for(Entry<String, List<String>> entry : map.entrySet()) {
             if(entry.getValue().size()<=1) {
                 answer += entry.getKey();
             }
         }
         answer = Arrays.stream(answer.split("")).sorted().collect(Collectors.joining());
         return answer;
    }
}
cs

 

  문자열을 Stream으로 만들어  Collectors.groupingBy(s1 -> s1)을 이용하여 같은 문자 끼리 그룹을 지어 map을 만든다.
  Arrays.stream(s.split("")).collect(Collectors.groupingBy(s1 -> s1));

  다음과 같은 맵이 생성된다.
  {a=[a, a, a], b=[b, b], c=[c, c, c], d=[d]}

  맵을 반복할때 key와 value 모두 필요하므로 map.entrySet()을 이용하여 반복한다. 이때 List인 value의 크기가 1이면 한번만
  나타난 문자가 된다. 문자(key)를 결합하여 문자열을 만든다.
  for(Entry<String, List<String>> entry : map.entrySet()) {
           if(entry.getValue().size()==1) {
                  answer += entry.getKey();
            }
   }

  문자 단위로 정렬하여 다시 문자열로 만든다. 
 
Arrays.stream(answer.split("")).sorted().collect(Collectors.joining());

 

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
    public String solution(String s) {
         Map<String, List<String>> map = Arrays.stream(s.split(""))
                                               .collect(Collectors.groupingBy(s1 -> s1));
         Set<Entry<String, List<String>>>  set = map.entrySet();
         Stream<String> stream = set.stream()
                                    .filter(v-> v.getValue().size()==1)
                                    .map(Map.Entry::getKey)
                                    .sorted();
         String answer = stream.collect(Collectors.joining());
         return answer;
    }
}
cs

 

 가운데 있었던 반복문을 스트림을 이용하여 filter로 걸러서 정렬까지 해결하였다.

 메서드 체이닝을 이용하면 1줄로도 가능하겠다.
  return Arrays.stream(s.split(""))
                       .collect(Collectors.groupingBy(s1 -> s1))
                       .entrySet()
                       .stream()
                       .filter(entry -> entry.getValue().size() <= 1)
                       .map(Map.Entry::getKey)
                       .sorted()
                       .collect(Collectors.joining());

 

728x90