[Programmers] 튜플

2023. 8. 17. 16:18Computer Sciences/Problem Solve

https://school.programmers.co.kr/learn/courses/30/lessons/64065

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 설명

정규식을 활용해야 하는 문제이다. 필자는 다음 순서대로 해결하였다.

  1. 가장 바깥쪽 중괄호를 제거한다.
  2. 나머지를 중괄호로 묶어서 분리한다.
  3. 배열 길이를 기준으로 오름차순 정렬한다.
  4. 배열을 탐색하며 현재 Set에 들어있지 않은 값을 추가한다.

위 순서를 따라 만든 코드는 다음과 같다.

코드

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.HashSet;

class Solution {
    public int[] solution(String s) {
        /***
          * 1. 제일 바깥 중괄호 제거
          * 2. 중괄호로 묶인 것으로 분리
          * 3. 배열 길이 기준으로 오름차순 정렬
          * 4. 현재까지 나오지 않은 없는 숫자를 추가
          * 5. 정답 반환
         ***/

        s = s.substring(1);
        s = s.substring(0, s.length() - 1);

        String pattern = "\\{([^}]+)\\}";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(s);

        ArrayList<int[]> arr = new ArrayList<>();

        while (m.find()) {
            String groupContent = m.group(1);
            String[] numbers = groupContent.split(",");
            int[] intArray = new int[numbers.length];

            for (int i = 0; i < intArray.length; i++) {
                intArray[i] = Integer.parseInt(numbers[i]);
            }

            arr.add(intArray);
        }

        arr.sort((arr1, arr2) -> {
            if (arr1.length > arr2.length) {
                return 1;
            }

            if (arr1.length < arr2.length) {
                return -1;
            }

            return 0;
        });

        HashSet<Integer> set = new HashSet<>();

        int[] answer = new int[arr.size()];
        int size = arr.size();
        for (int i = 0; i < size; i++) {
            int[] intArr = arr.get(i);

            for (int j = 0; j < intArr.length; j++) {
                if (!set.contains(intArr[j])) {
                    answer[i] = intArr[j];
                    set.add(intArr[j]);
                }
            }
        }

        return answer;
    }
}

정답 확인을 받고 다른 사람들의 풀이를 살펴보았는데 replaceAll과 set을 활용하여 짧은 코드로 제출하신 분의 코드가 가장 인기있었다. 개인적으로 그 다음 풀이가 더 좋아서 이를 소개하겠다.

import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class Solution {
    public int[] solution(String s) {
        Map<String, Integer> map = new HashMap<>();
        Pattern pattern = Pattern.compile("[0-9]+");
        Matcher matcher = pattern.matcher(s);
        while (matcher.find()) {
            String n = matcher.group();
            map.put(n, map.getOrDefault(n, 0) + 1);
        }
        int size = map.size();
        int[] answer = new int[size];
        for (String key: map.keySet()) {
            answer[size - map.get(key)] = Integer.parseInt(key);
        }
        return answer;
    }
}

먼저 중괄호가 아닌 숫자만을 추출한다. 그리고 HashMap에 숫자의 등장 빈도를 저장한다. 숫자의 등장 빈도가 곧 튜플의 순서를 말하기 때문에 가능한 방식이다. 그 다음 size - map.get(key)를 통해 위치를 지정하고 해당 숫자를 저장하여 정답을 만들어낸다. 이 방식이 for 문도 줄여줄 뿐 아니라 정렬도 하지 않아도 되기 때문에 더 좋다고 생각한다.

'Computer Sciences > Problem Solve' 카테고리의 다른 글

[Programmers] 피로도  (0) 2023.08.17
[Programmers] [1차] 뉴스 클러스터링  (0) 2023.08.17
[Programmers] 할인 행사  (0) 2023.08.17
[Programmers] 교점에 별 만들기  (0) 2023.08.16
[Programmers] [1차] 캐시  (0) 2023.08.16