Algorithm/Java

프로그래머스 - 옹알이 (2) JAVA :: 133499

고고마코드 2022. 12. 19. 15:24
반응형

문제링크

코딩테스트 연습 - 옹알이 (2) | 프로그래머스 스쿨 (programmers.co.kr)


문제 이해하기

  • 발음할 수 있는 단어는 “aya”, “ye”, “woo”, “ma” 4개의 단어 뿐이다.
  • 중복되어 나열된 단어는 발음할 수 없다.
    • 불가능 : “ayaaya”, “yeye”, “woowoo”, “mamama”
    • 가능 : “ayaye”, “wooma”, “mawoo”, “yemawoo”, “mawooma”
  • 중복되지만 않고, 발음할 수 있는 단어만 나열되면 된다.

문제풀이

1번 풀이 (스택)

이전 단어의 중복을 체크하기 위해 Stack을 활용

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Solution {
    public int solution(String[] babbling) {
        List<String> babbles = new ArrayList<String>();
        babbles.add("aya"); babbles.add("ye"); babbles.add("woo"); babbles.add("ma");

        int answer = 0;
        for(String babble : babbling) {
            boolean possible = true;
            Stack<String> possibles = new Stack<String>();
            StringBuilder sb = new StringBuilder();

            for(char ch : babble.toCharArray()) {
                sb.append(ch);
                if(babbles.contains(sb.toString())) {
                    if(!possibles.isEmpty() && possibles.peek().equals(sb.toString())) {
                        possible = false;
                        break;
                    } else {
                        possibles.add(sb.toString());
                        sb.setLength(0);
                    }
                } 
            }

            if(sb.length() == 0 && possible) {
                answer++;
            }
        }

        return answer;
    }
}

핵심 코드 - 1

if(babbles.contains(sb.toString())) { ... }

문자열을 단어 단위로 쪼개기 위해 한 문자씩 문자열을 가져와 사전에 넣었던 단어 리스트에 포함되는지 체크한다.

핵심 코드 - 2

if(!possibles.isEmpty() && possibles.peek().equals(sb.toString())) {
    possible = false;
    break;
} else {
    possibles.add(sb.toString());
    sb.setLength(0);
}
  • 기존에 스택이 비어 있다면 단어를 넣는다.
  • 스택이 비어 있지 않다면 스택의 마지막 단어(peek)와 현재 단어(sb.toString())가 같은지 비교한다.
  • 단어가 같다면 중복처리로 인해 현재 문자열의 반복 수행을 그만둔다.
  • 단어가 같지 않다면 스택에 Push하고, 단어를 찾았으니 단어를 초기화 시킨다. (sb.setLength(0)

핵심 코드 - 3

if(sb.length() == 0 && possible) {
    answer++;
}

단어를 모두 찾았는데도 StringBuilder의 값이 남아있다면 못 찾은 단어가 남은 것이므로 옹알이 하지 못한다.

2번 풀이 (정규식)

2개의 정규식을 활용해 중복체크단어조합체크를 진행한다.

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

public class Solution {
    public int solution2(String[] babbling) {
        int answer = 0;
        Pattern pattern1 = Pattern.compile("(ayaaya|yeye|woowoo|mama)+");
        Pattern pattern2 = Pattern.compile("^(aya|ye|woo|ma)+?$");
        Matcher matcher = null;

        for(String babble : babbling) {
            matcher = pattern1.matcher(babble);
            if(!matcher.find()) {
                matcher = pattern2.matcher(babble);
                if(matcher.find()) {
                    answer++;
                }
            }
        }

        return answer;
    }
}

1번 정규식

  • "(ayaaya|yeye|woowoo|mama)+"
    각 단어(ayaaya, yeye, woowoo, mama)가 1개라도 있는 경우 중복으로 판단

2번 정규식

  • "^(aya|ye|woo|ma)+?$"
    처음부터 끝까지 발음할 수 있는 단어(aya, ye, woo, ma)로 1개 이상 포함된 경우

1번 정규식으로 중복 체크를 한 후, 2번 정규식으로 발음할 수 있는 단어의 조합인지 판단한다.
반응형