알고리즘/프로그래머스

[프로그래머스] 옹알이 (2) - Java

반응형

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

 

프로그래머스

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

programmers.co.kr


문제

문제 설명
머쓱이는 태어난 지 11개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음과 네 가지 발음을 조합해서 만들 수 있는 발음밖에 하지 못하고 연속해서 같은 발음을 하는 것을 어려워합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return하도록 solution 함수를 완성해주세요.


제한사항

  • 1 ≤ babbling의 길이 ≤ 100
  • 1 ≤ babbling[i]의 길이 ≤ 30
  • 문자열은 알파벳 소문자로만 이루어져 있습니다.


입출력 예

babbling result
["aya", "yee", "u", "maa"] 1
["ayaye", "uuu", "yeye", "yemawoo", "ayaayaa"] 2

입출력 예 설명

입출력 예 #1

["aya", "yee", "u", "maa"]에서 발음할 수 있는 것은 "aya"뿐입니다. 따라서 1을 return합니다.

입출력 예 #2

["ayaye", "uuuma", "yeye", "yemawoo", "ayaayaa"]에서 발음할 수 있는 것은 "aya" + "ye" = "ayaye", "ye" + "ma" + "woo" = "yemawoo"로 2개입니다. "yeye"는 같은 발음이 연속되므로 발음할 수 없습니다. 따라서 2를 return합니다.


유의사항
네 가지를 붙여 만들 수 있는 발음 이외에는 어떤 발음도 할 수 없는 것으로 규정합니다. 예를 들어 "woowo"는 "woo"는 발음할 수 있지만 "wo"를 발음할 수 없기 때문에 할 수 없는 발음입니다.


풀이

풀이 과정

발음할 수 있는 단어의 비교를 위해 발음이 가능한 4가지 단어 "aya", "ye", "woo", "ma" 를 Map에 저장한다.

class Solution {
    Map<String, Boolean> map = new HashMap<>(); // 발음 가능한 단어 판별을 위한 Map 선언
    
    public int solution(String[] babbling) {
        int answer = 0;
        String[] available = {"aya", "ye", "woo", "ma"}; // 발음 가능한 단어
        
        for(String word : available){
            map.put(word, true);
        }
    }
}

 

입력받은 babbling 배열의 각 원소들의 단어 발음 가능 여부를 판단하는 함수 canPronounce를 생성한다.
이 함수에서 입력받은 단어의 첫 번째 인덱스 부터 인덱스를 1씩 증가시키며 Map에 저장된 발음 가능한 단어와 비교를 하여 그 단어만큼 잘라내고 단어의 길이가 0이 되거나 종료 인덱스가 단어의 길이를 초과할 때까지 반복한다.
탐색 중 연속으로 사용되는 단어가 존재하거나 탐색하는 단어의 길이가 4이상인 경우 ( 발음 가능한 단어 중 가장 긴단어가 3글자 이므로) false를 반환하고 탐색이 종료되었을 때 최종적으로 남아있는 단어의 길이가 0보다 크다면 역시 발음할 수 없는 단어 이므로 false를 반환한다.

먼저 단어를 잘라낼 인덱스와 결과값을 저장할 변수를 선언한다.

public boolean canPronounce(String word) {
    int end = 1;
    boolean result = true;
}

 

단어의 길이가 0이 되거나 종료 인덱스가 단어의 길이를 초과할 때 까지 단어를 자르며 비교한다.
단어를 앞에서 부터 종료 인덱스 까지 자른 값이 map에 존재하지 않는 경우는 종료인덱스를 증가시켜 재탐색을 한다.

// 단어의 길이가 0이거나 종료 인덱스가 단어 길이를 초과할 때까지 반복
while(word.length() > 0 && end <= word.length()) {
    // 단어를 앞에서 부터 end 까지 자른 값이 map에 존재하지 않는 경우
    if(map.get(word.substring(0, end)) == null){
        end++; // 종료 인덱스를 증가
    } 
}

 

잘라낸 값이 map에 존재하는 경우라면 이전에 사용된 값인지 체크가 필요하다.
이전에 사용된 단어를 저장할 변수를 선언하고 현재 탐색중인 값과 같다면, 즉 연속된 발음이라면 즉시 false를 반환,
연속된 발음이 아니라면 이전에 사용된 변수값을 현재 탐색중인 값으로 세팅,  단어의 첫 번째 인덱스부터 종료 인덱스까지를 잘라내고 종료 인덱스를 1로 초기화한다.

// 단어를 앞에서 부터 end 까지 자른 값이 map에 존재하는 경우
else {
    if(word.substring(0, end).equals(before)){  // 연속된 발음인 경우
        return false;                           // 발음 불가능한 단어
    } else{                                     // 연속되지 않은 발음인 경우
        before = word.substring(0, end);        // 이전에 사용된 발음값으로 세팅
        word = word.substring(end);             // 존재하는 단어만큼 잘라내고
        end = 1;                                // 종료 인덱스를 1로 초기화
    }
}

 

while문이 종료 되었을 때 단어에 남아있는 문자가 있다면 발음할 수 없는 단어이므로 false를 반환한다.

// 최종 단어에 남아있는 문자가 있으면 발음할 수 없는 단어
if(word.length() > 0) result = false;

return result;

 

생성한 함수를 이용하여 babbling 배열을 순회하며 각 단어의 발음 여부를 판단하여 발음할 수 있는 단어의 개수를 return 한다.

for(String word : babbling){
    if(canPronounce(word)) answer++; // 발음이 가능하면 카운트 증가
}

return answer;

최종 코드

import java.util.*;

class Solution {
    Map<String, Boolean> map = new HashMap<>(); // 발음 가능한 단어 판별을 위한 Map 선언
    
    public int solution(String[] babbling) {
        int answer = 0;
        String[] available = {"aya", "ye", "woo", "ma"}; // 발음 가능한 단어
        
        for(String word : available){
            map.put(word, true);
        }
        for(String word : babbling){
            if(canPronounce(word)) answer++; // 발음이 가능하면 카운트 증가
        }
        
        return answer;
    }
    
    /*
     * 단어 발음 가능 여부 판단
     */
    public boolean canPronounce(String word) {
        int end = 1;
        boolean result = true;
        String before = ""; // 이전에 사용된 발음
        
        // 단어의 길이가 0이거나 종료 인덱스가 단어 길이를 초과할 때까지 반복
        while(word.length() > 0 && end <= word.length()) {
            // 단어를 앞에서 부터 end 까지 자른 값이 map에 존재하지 않는 경우
            if(map.get(word.substring(0, end)) == null){
                end++; // 종료 인덱스를 증가
            } 
            // 단어를 앞에서 부터 end 까지 자른 값이 map에 존재하는 경우
            else {
                if(word.substring(0, end).equals(before)){  // 연속된 발음인 경우
                    return false;                           // 발음 불가능한 단어
                } else{                                     // 연속되지 않은 발음인 경우
                    before = word.substring(0, end);        // 이전에 사용된 발음값으로 세팅
                    word = word.substring(end);             // 존재하는 단어만큼 잘라내고
                    end = 1;                                // 종료 인덱스를 1로 초기화
                }
            }
            if(end > 3) return false;       // 종료 인덱스가 3을 초과하면 false를 반환
                                            // 발음 가능한 단어들 중 가장 긴 단어가 3글자이기 때문
        }
        
        // 최종 단어에 남아있는 문자가 있으면 발음할 수 없는 단어
        if(word.length() > 0) result = false;
        
        return result;
    }
}