본문 바로가기

코딩 테스트/프로그래머스

[프로그래머스] 튜플

프로그래머스

2019 카카오 개발자 겨울 인턴십

 

프로그래머스

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

programmers.co.kr

[1차] 뉴스 클러스터링

 

문제 정리
1. 원소에 정해진 순서가 있기 때문에 원소의 순서가 다르면 서로 다른 튜플(1,2,3) ≠ (1,3,2)
2. 예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는 {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}} → 순서가 바뀌어도 상관없다.
3. 매개변수 s는 숫자와 '{', '}', '로만 구성 그리고 0으로 시작할 수 없다.
4, 중복된 원소는 존재하지 않는다.
5. 특정 튜플을 표한하는 집합이 담긴 문자열 s를 이용해서 -> 튜플 배열을 return 하는 문제

 

시작하기 전 접근 방법
1. 매개변수 s문자열에서 split를 이용하여 공통으로 되어 있는 }, {문자를 제거한다.
2. 제거하면 가장 앞, 뒤에 { 와 }가 남기 때문에 배열[0]과 배열[length-1]에서 해당 괄호를 제거한다.
3. 괄호를 제거한 s문자열을 확인하면 2차원 배열로 표현이 가능해진다.
4. 각각 값을 2차원배열을 만들어서 2차원 배열에 저장한다.
5. 중복확인을 하기 위해서 HashSet을 이용한다 -> HashSet은 중복을 포함할 수 없기 때문에
6. 숫자를 String형식으로 되어 있기 때문에 hashSet을 이용해서 중복을 확인하여 배열에 저장한다.
7 배열에 저장한 String을 답에서는 int배열로 만들어야 하기 때문에 Integer.parseInt을 이용해서 String을 int로 변경해서 저장한다.

 

테스트 예제 값

 

 

1번과 2번 과정을 하여 문자열을 분리한다. 1번 과정을 통해 공통인 부분을 경계로 split를 이용하여 분리를 하여 배열에 저장한 후 맨 앞과 맨뒤배열은 괄호가 있기 때문에 괄호를 정리해 준다.
	String[] splitS = s.split("\\},\\{");     
        // ["2", "2,1", "2,1,3", "2,1,3,4"] -> [2, 1, 3, 4]
        // ["4,2,3", "3", "2,3,4,1", "2,3" ] -> [3, 2, 4, 1]
        
         // 배열의 가장 앞 문자열, 배열의 가장 뒷 문자열에서 '{' , '}' 문자 제거
        splitS[0] = splitS[0].replaceAll("[{}]","");
        splitS[splitS.length-1] = splitS[splitS.length-1].replaceAll("[{}]","");

 

 

3번과 4번 과정을 진행해서 2차원 배열에 해당 값들을 저장한다.
 	String[][] strArr = new String[splitS.length][];
        for(int i=0; i<splitS.length; i++){
            String[] value = splitS[i].split(",");
            strArr[value.length-1] = value;
        }

 

 

이 문제에서 가장 중요한 부분이 5번이라고 생각했다. 2차원 배열에 저장되어 있는 String 형식에 튜플은 중복값이 존재한다. 하지만 마지막 answer 배열은 중복을 제외한 값이 저장되어 있는 배열이기 때문에 중복값을 제거하는 방법을 생각해야 했다.
HashSet을 이용하여 중복문자를 분류하고 중복이 아닌 값들만 1차원 배열을 만들어서 저장하였다. 일단은 매개변수가 String이기 때문에 저장되는 배열도 String 배열로 생성한다.
	HashSet<String> result = new HashSet<>();
        String[] check = new String[strArr.length];
        for(int i=0; i<strArr.length; i++){
            for(int j=0; j<strArr[i].length; j++){
                if(!result.contains(strArr[i][j])){
                    result.add(strArr[i][j]);
                    check[i] = strArr[i][j];
                }
            }
        }

 

 

마지막으로 7번을 구현하여 String으로 계산하였던 값을 int 배열에 저장하는 방식이다. String 배열을 구한 길이만큼 int배열도 같은 길이를 가지기 때문에 String배열에 저장한 배열 길이만큼 int배열을 생성하여 String문자를 int로 바꾸는 Integer.parseInt를 이용하여 타입 변환을 하여 저장하면 끝난다. 반복문을 통해서 index 범위 0부터 하나씩 증가하여 저장한다.
	int[] answer = new int[check.length];
        for (int i = 0; i < check.length ; i++) {
            answer[i] = Integer.parseInt(check[i]);
        }

 

 

실수했던 부분

처음에는 HashSet을 이용하여 중복체크를 진행한 후 hashSet에 들어있는 값을 get을 이용하여 int배열에 저장하는 방식으로 코드를 작성하였다. 하지만 이렇게 코드를 작성하였을 때 원하는 answer값이 나오지 않았다. 필요한 int 값은 다 가져오지만 순서를 다르게 가져왔다. HashSet에서 바로 값을 가져와서 저장하다 보니 순서를 다르게 가져오는 방법이어서 어떻게 처리를 해야지 많인 고민과 삽질을 반복하였다. 그래서 HashSet은 중복을 확인하는 용도로 사용하고 HashSet에 값을 저장할 때 배열에도 같이 저장하여 처리하는 방법을 사용해 보았다. 그래서 String문자열 배열에 저장하여 최종 나온 String배열을 인덱스가 0인 번호부터 하나씩 String -> int로 Integer.parseInt를 이용해서 구해야 하는 answer배열을 만들었다.

중복을 확인하는 방법을 hashSet으로 하고 다음 단계를 어떻게 진행해서 구하고자 하는 answer값을 해야 하는지 삽질이 필요하고 간단하게 생각해서 끝나는 문제가 아닌 실수가 발생하는 부분을 고민해야 하는 문제였다...

 

 

전체 코드

 

더보기
import java.util.ArrayList;
import java.util.HashSet;

public class Solution {
    public int[] solution(String s) {
    	
        String[] splitS = s.split("\\},\\{");     
        // ["2", "2,1", "2,1,3", "2,1,3,4"] -> [2, 1, 3, 4]
        // ["4,2,3", "3", "2,3,4,1", "2,3" ] -> [3, 2, 4, 1]
        
        // 배열의 가장 앞 문자열, 배열의 가장 뒷 문자열에서 '{' , '}' 문자 제거
        splitS[0] = splitS[0].replaceAll("[{}]","");
        splitS[splitS.length-1] = splitS[splitS.length-1].replaceAll("[{}]","");

        String[][] strArr = new String[splitS.length][];
        for(int i=0; i<splitS.length; i++){
            String[] value = splitS[i].split(",");
            strArr[value.length-1] = value;
        }
        
        HashSet<String> result = new HashSet<>();
        String[] check = new String[strArr.length];
        for(int i=0; i<strArr.length; i++){
            for(int j=0; j<strArr[i].length; j++){
                if(!result.contains(strArr[i][j])){
                    result.add(strArr[i][j]);
                    check[i] = strArr[i][j];
                }
            }
        }        
        
        int[] answer = new int[check.length];
        for (int i = 0; i < check.length ; i++) {
            answer[i] = Integer.parseInt(check[i]);
        }
        return answer;
    }
}