[프로그래머스/JAVA] 성격 유형 검사하기

2024. 9. 30. 11:02·TIL 🔖/코딩테스트

문제 설명 

나만의 카카오 성격 유형 검사지를 만들려고 합니다.
성격 유형 검사는 다음과 같은 4개 지표로 성격 유형을 구분합니다. 성격은 각 지표에서 두 유형 중 하나로 결정됩니다.

지표 번호 성격 유형
1번 지표
라이언형(R), 튜브형(T)
2번 지표
콘형(C), 프로도형(F)
3번 지표
제이지형(J), 무지형(M)
4번 지표
어피치형(A), 네오형(N)


4개의 지표가 있으므로 성격 유형은 총 16(=2 x 2 x 2 x 2)가지가 나올 수 있습니다. 예를 들어, "RFMN"이나 "TCMA"와 같은 성격 유형이 있습니다.
 
검사지에는 총 n개의 질문이 있고, 각 질문에는 아래와 같은 7개의 선택지가 있습니다.

  • 매우 비동의
  • 비동의
  • 약간 비동의
  • 모르겠음
  • 약간 동의
  • 동의
  • 매우 동의

각 질문은 1가지 지표로 성격 유형 점수를 판단합니다.
예를 들어, 어떤 한 질문에서 4번 지표로 아래 표처럼 점수를 매길 수 있습니다.

선택지 성격 유형 점수
매우 비동의 네오형 3점
비동의 네오형 2점
약간 비동의 네오형 1점
모르겠음
어떤 성격 유형도 점수를 얻지 않습니다
약간 동의 어피치형 1점
동의 어피치형 2점
매우 동의 어피치형 3점


이때 검사자가 질문에서 약간 동의 선택지를 선택할 경우 어피치형(A) 성격 유형 1점을 받게 됩니다. 만약 검사자가 매우 비동의 선택지를 선택할 경우 네오형(N) 성격 유형 3점을 받게 됩니다.
위 예시처럼 네오형이 비동의, 어피치형이 동의인 경우만 주어지지 않고, 질문에 따라 네오형이 동의, 어피치형이 비동의인 경우도 주어질 수 있습니다.
하지만 각 선택지는 고정적인 크기의 점수를 가지고 있습니다.

  • 매우 동의나 매우 비동의 선택지를 선택하면 3점을 얻습니다.
  • 동의나 비동의 선택지를 선택하면 2점을 얻습니다.
  • 약간 동의나 약간 비동의 선택지를 선택하면 1점을 얻습니다.
  • 모르겠음 선택지를 선택하면 점수를 얻지 않습니다.

검사 결과는 모든 질문의 성격 유형 점수를 더하여 각 지표에서 더 높은 점수를 받은 성격 유형이 검사자의 성격 유형이라고 판단합니다. 단, 하나의 지표에서 각 성격 유형 점수가 같으면, 두 성격 유형 중 사전 순으로 빠른 성격 유형을 검사자의 성격 유형이라고 판단합니다.
 
질문마다 판단하는 지표를 담은 1차원 문자열 배열 survey와 검사자가 각 질문마다 선택한 선택지를 담은 1차원 정수 배열 choices가 매개변수로 주어집니다. 이때, 검사자의 성격 유형 검사 결과를 지표 번호 순서대로 return 하도록 solution 함수를 완성해주세요.


제한 조건

  • 1 ≤ survey의 길이 ( = n) ≤ 1,000
    • survey의 원소는 "RT", "TR", "FC", "CF", "MJ", "JM", "AN", "NA" 중 하나입니다.
    • survey[i]의 첫 번째 캐릭터는 i+1번 질문의 비동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.
    • survey[i]의 두 번째 캐릭터는 i+1번 질문의 동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.
  • choices의 길이 = survey의 길이
    • choices[i]는 검사자가 선택한 i+1번째 질문의 선택지를 의미합니다.
    • 1 ≤ choices의 원소 ≤ 7
choices뜻
1매우 비동의
2비동의
3약간 비동의
4모르겠음
5약간 동의
6동의
7매우 동의

나의 풀이

import java.util.HashMap;
import java.util.Map;

class Solution {
    public String solution(String[] survey, int[] choices) {
        Map<Character,Integer> scoreMap = new HashMap<>();
        
        scoreMap.put('R',0);
        scoreMap.put('T',0);
        scoreMap.put('C',0);
        scoreMap.put('F',0);
        scoreMap.put('J',0);
        scoreMap.put('M',0);
        scoreMap.put('A',0);
        scoreMap.put('N',0);
        
        for(int i = 0; i < survey.length; i++){
            String type = survey[i];
            int choice = choices[i];
            
            char disagreeType = type.charAt(0);
            char agreeType = type.charAt(1);
            
            if (choice <= 3) {
                scoreMap.put(disagreeType, scoreMap.get(disagreeType) + (4-choice));
            } else if (choice >= 5) {
                scoreMap.put(agreeType, scoreMap.get(agreeType) + (choice -4));
            }
        }
        
         StringBuilder result = new StringBuilder();
        result.append(scoreMap.get('R') >= scoreMap.get('T') ? 'R' : 'T');
        result.append(scoreMap.get('C') >= scoreMap.get('F') ? 'C' : 'F');
        result.append(scoreMap.get('J') >= scoreMap.get('M') ? 'J' : 'M');
        result.append(scoreMap.get('A') >= scoreMap.get('N') ? 'A' : 'N');

        return result.toString();
    }
}

 

문제 접근 방법 

문제 이해하기

성격 유형 검사에서 각 질문의 답변을 바탕으로, 사용자의 성격을 4개의 지표를 통해 16가지 유형 중 하나로 결정하는 문제이다. 각 질문은 하나의 지표에 대응하며, 사용자의 선택에 따라 성격 유형에 점수가 더해진다.

  • 1번 지표: 라이언형(R), 튜브형(T)
  • 2번 지표: 콘형(C), 프로도형(F)
  • 3번 지표: 제이지형(J), 무지형(M)
  • 4번 지표: 어피치형(A), 네오형(N)

각 질문에 대한 답변을 얻은 점수를 토대로, 각 지표에서 더 높은 점수를 받은 성격 유형이 최종적으로 결졍된다

  • 매우 동의(7) ~ 매우 비동의(1)까지 7개의 선택지가 있으며, 선택에 따라 성격 유형에 점수가 주어진다.
  • 동의 선택지는 두 번째 유형에 점수를 더하고, 비동의 선택지는 첫 번째 유형에 점수를 더한다.
  • 선택지가 같으면 사전순으로 빠른 성격 유형을 선택한다.
문제 접근하기 

문제에서 요구하는 핵심 

  • 질문에 대한 선택지에 따라 성격 유형 점수를 계산하는 것
  • 최종적으로 지표별로 더 높은 점수를 받은 성격 유형을 선택하는 것

입력으로 주어진 survey와 choices 배열을 순회하면서 각 지표별로 점수를 계산한 후, 각 지표에서 더 높은 점수를 받은 성격 유형을 결정하는 과정을 수행한다. 
 
1. 자료 구조 설정

  • 성격 유형의 점수를 저장하기 위해 각 유형을 키로 하고, 점수를 값으로 가지는 HashMap을 사용한다.
  • 모든 성격 유형을 미리 0점으로 초기화한 후, 선택지를 순차적으로 확인하면서 점수를 누적한다.

2. 점수 계산

  • 각 선택지(choices) 값에 따라 동의 또는 비동의 쪽에 점수를 더한다.
  • 선택지가 4일 경우에는 점수를 주지 않고 넘어가며, 비동의 쪽은 선택지 값에 따라 첫 번째 캐릭터의 점수를, 동의 쪽은 두 번째 캐릭터의 점수를 추가한다.

3. 최종 결과 계산

  • 각 지표별로 두 성격 유형 중 더 높은 점수를 받은 성격 유형을 선택하고, 만약 점수가 같다면 사전순으로 더 빠른 성격 유형을 선택해 최종 성격을 결정한다.

코드 풀이

1. HashMap을 이용한 성격 유형 점수 저장

Map<Character, Integer> scoreMap = new HashMap<>();
scoreMap.put('R', 0);
scoreMap.put('T', 0);
scoreMap.put('C', 0);
scoreMap.put('F', 0);
scoreMap.put('J', 0);
scoreMap.put('M', 0);
scoreMap.put('A', 0);
scoreMap.put('N', 0);
  • HashMap은 키-값 쌍으로 데이터를 저장하는 자료 구조이다. 여기서 각 성격 유형이 키(Character)로, 해당 성격 유형의 점수가 값(Integer)으로 저장된다.
  • 코드에서 미리 각 성격 유형에 대해 0점을 할당하며, 이후 점수를 추가하는 방식으로 업데이트된다.

2. 선택지에 따른 점수 부여

for (int i = 0; i < survey.length; i++) {
    String type = survey[i];
    int choice = choices[i];
    
    char disagreeType = type.charAt(0); // 비동의에 해당하는 성격 유형
    char agreeType = type.charAt(1);    // 동의에 해당하는 성격 유형
    
    // 선택지에 따른 점수 계산
    if (choice <= 3) { // 비동의 선택지일 경우
        scoreMap.put(disagreeType, scoreMap.get(disagreeType) + (4 - choice));
    } else if (choice >= 5) { // 동의 선택지일 경우
        scoreMap.put(agreeType, scoreMap.get(agreeType) + (choice - 4));
    }
}
  • for 루프는 주어진 질문 수(survey.length)만큼 반복한다. survey[i]와 choices[i]는 각각 i번째 질문의 성격 유형 지표와 사용자가 선택한 답변을 나타낸다.
  • String.charAt(): survey[i]는 두 개의 캐릭터로 이루어져 있으며, 첫 번째 캐릭터는 비동의 선택지에 해당하는 성격 유형, 두 번째 캐릭터는 동의 선택지에 해당하는 성격 유형입니다. charAt(0)으로 첫 번째 캐릭터를, charAt(1)으로 두 번째 캐릭터를 추출합니다.
  • 점수 계산 로직
    • 비동의 선택지 (1 ~ 3): choice 값이 1~3일 때는 비동의 선택지에 해당하는 성격 유형에 점수를 더한다. 이때 선택지가 매우 비동의(1)일 경우 3점, 비동의(2)일 경우 2점, 약간 비동의(3)일 경우 1점이 부여된다.
    • 동의 선택지 (5 ~ 7): choice 값이 5~7일 때는 동의 선택지에 해당하는 성격 유형에 점수를 더한다. 이때 매우 동의(7)일 경우 3점, 동의(6)일 경우 2점, 약간 동의(5)일 경우 1점이 부여된다.
    • 모르겠음 (4): 선택지가 4일 경우에는 아무 성격 유형에도 점수가 부여되지 않으므로 아무 작업도 하지 않는다.

3. 최종 성격 유형 결정

  • StringBuilder: 성능 면에서 문자열을 효율적으로 이어 붙이기 위해 사용한다. String 객체는 불변이기 때문에 문자열을 이어 붙일 때 새로운 객체가 생성되므로 StringBuilder를 사용하여 성격 유형 문자열을 만들면 더 효율적이다.
  • 점수 비교 
    • 각 지표에서 scoreMap에 저장된 점수를 비교해 더 높은 점수를 받은 성격 유형을 선택한다.
    • 예를 들어, 첫 번째 지표(R, T)에서 R의 점수가 T보다 크거나 같으면 'R'을, 그렇지 않으면 'T'를 결과 문자열에 추가한다.
    • 만약 점수가 같을 경우에도 사전순으로 빠른 성격 유형을 선택한다.

4. 결과 반환

  • toString() 메서드를 사용해 StringBuilder에 담긴 성격 유형 문자열을 반환한다.
'TIL 🔖/코딩테스트' 카테고리의 다른 글
  • [프로그래머스/JAVA] 달리기경주
  • [프로그래머스/JAVA] 개인정보 수집 유효기간
  • [프로그래머스/JAVA] 햄버거 만들기 (Stack 으로 풀이하기)
  • [프로그래머스/JAVA] 옹알이 (2) String vs StringBuilder
fargoe
fargoe
    fargoe
    fargoewave
    fargoe
    GitHub
    전체
    오늘
    어제
    • 분류 전체보기 (166)
      • TIL 🔖 (140)
        • TIL (69)
        • 코딩테스트 (71)
      • DEV (14)
        • Java & Spring (7)
        • MySQL (3)
        • Git&Github (4)
      • 개발지식 (10)
        • 알고리즘 (2)
        • 자료구조 (8)
        • CS (0)
      • 3D (1)
        • Unity (1)
      • ETC (0)
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
fargoe
[프로그래머스/JAVA] 성격 유형 검사하기
상단으로

티스토리툴바