Skip to main content

πŸ“ 133499 μ˜Ήμ•Œμ΄(2)


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

1. 문제 μš”μ•½

  • λ¬Έμžμ—΄μ΄ "aya", "ye", "woo", "ma" λ„€ κ°€μ§€ 발음으둜만 이루어져 있고, 같은 λ°œμŒμ„ μ—°μ†ν•΄μ„œ μ“°λ©΄ μ•ˆ λœλ‹€

2. 접근방법

  • words λ°°μ—΄ μ„ μ–Έν•˜κ³  κ°€λŠ₯ν•œ 발음 넣어두기
  • 각 λ¬Έμžμ—΄ b에 λŒ€ν•΄ μ²˜μŒλΆ€ν„° μ°¨λ‘€λŒ€λ‘œ ν™•μΈν•˜κΈ°
  • startsWith(w, i) μ¨μ„œ ν˜„μž¬ μœ„μΉ˜μ—μ„œ κ°€λŠ₯ν•œ 발음이 μ‹œμž‘λ˜λŠ”μ§€ ν™•μΈν•˜κΈ°
  • 같은 발음이 직전에 μ‚¬μš©λœ 것(prev)와 κ°™μœΌλ©΄ κ±΄λ„ˆλ›°κΈ°
  • λκΉŒμ§€ 쑰건을 λ§Œμ‘±ν•˜λ©΄ μœ νš¨ν•œ λ‹¨μ–΄λ‘œ 카운트

3. μ •λ‹΅μ½”λ“œ

class Solution {
    public int solution(String[] babbling) {
        String[] words = {"aya", "ye", "woo", "ma"};
        int count = 0;
        
        for (String b : babbling) {
            String prev = ""; // 이전 λ°œμŒμ„ μ €μž₯ν•΄μ„œ 연속 확인
            boolean valid = true; // μ²˜μŒμ—λŠ” μœ νš¨ν•˜λ‹€κ³  κ°€μ •ν•˜κ³  μ‹œμž‘
            int i = 0;
            
            while (i < b.length()) {
                boolean matched = false;
                
                for (String w : words) {
                    // bλΌλŠ” λ¬Έμžμ—΄μ΄ i번째 μΈλ±μŠ€λΆ€ν„° μ‹œμž‘ν•΄μ„œ wλΌλŠ” λ¬Έμžμ—΄λ‘œ μ‹œμž‘ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” λ©”μ„œλ“œ
                    if (b.startsWith(w, i) && !w.equals(prev)) {
                        prev = w;
                        i += w.length();
                        matched = true;
                        break;
                    }
                }
                
                // λ„€ κ°€μ§€ 발음 쀑 ν•˜λ‚˜λ„ λ§€μΉ­ μ•ˆ 되면 μœ νš¨ν•˜μ§€ μ•ŠμŒ
                if (!matched) {
                    valid = false;
                    break;
                }
            }
            // λκΉŒμ§€ 쑰건을 λ§Œμ‘±ν–ˆλ‹€λ©΄ count++
            if (valid) count++;
        }
        
        return count;
    }
}

4. μ •κ·œμ‹μœΌλ‘œ ν‘ΈλŠ” 법

import java.util.regex.*;

class Solution {
    public int solution(String[] babbling) {
        String[] words = {"aya", "ye", "woo", "ma"};
        int count = 0;
        
        String pattern = "^(aya|ye|woo|ma)(?!\\1)(aya|ye|woo|ma)*(?!\\1)$";
        Pattern regex = Pattern.compile(pattern);
        
        for (String b : babbling) {
            Matcher matcher = regex.matcher(b);
            if (matcher.matches()) {
                count++;
            }
        }
        
        return count;
    }
}

image.png


μ •κ·œμ‹λ§ŒμœΌλ‘œ ν’€λ €κ³  ν•˜λ©΄ μƒλ‹Ήνžˆ λ³΅μž‘ν•΄μ§„λ‹€. μ •κ·œμ‹μœΌλ‘œλŠ” "ν—ˆμš©λ‹¨μ–΄λ§Œ 포함"κΉŒμ§€λ§Œ κ²€μ‚¬ν•˜κ³ , μ—°μ†λœ 단어λ₯Ό κΈˆμ§€ν•˜λŠ” 쑰건은 λ”°λ‘œ 둜직으둜 μ²˜λ¦¬ν•˜λŠ”κ²Œ κΉ”λ”ν•˜λ‹€.

import java.util.regex.*;

class Solution {
    public int solution(String[] babbling) {
        int count = 0;
        
        // ν—ˆμš©λœ λ‹¨μ–΄λ‘œλ§Œ κ΅¬μ„±λœ 경우
        String validPattern = "^(aya|ye|woo|ma)+$";
        // 같은 단어가 μ—°μ†λ˜λŠ” 경우 κ±ΈλŸ¬λ‚΄κΈ°
        String invalidPattern = "(ayaaya|yeye|woowoo|mama)";
        
        Pattern valid = Pattern.compile(validPattern);
        Pattern invalid = Pattern.compile(invalidPattern);
        
        for (String b : babbling) {
            if (valid.matcher(b).matches() && !invalid.matcher(b).find()) {
                count++;
            }
        }
        
        return count;
    }
}

1. "^(aya|ye|woo|ma)+$"

λ¬Έμžμ—΄ 전체가 aya, ye, woo, ma 쀑 ν•˜λ‚˜ μ΄μƒμœΌλ‘œλ§Œ κ΅¬μ„±λ˜μ–΄μ•Ό ν•œλ‹€λŠ” λœ»μ΄λ‹€.

^(aya|ye|woo|ma)+$

1. ^

  • λ¬Έμžμ—΄μ˜ μ‹œμž‘
  • "abc" λ¬Έμžμ—΄μ—μ„œ ^a 라고 ν•˜λ©΄ a둜 μ‹œμž‘ν•΄μ•Ό ν•œλ‹€λŠ” λœ»μ΄λ‹€.

2. (aya | ye | woo | ma)

  • κ΄„ν˜Έ μ•ˆμ˜ μ—¬λŸ¬ 선택지 쀑 ν•˜λ‚˜
  • aya λ˜λŠ” ye λ˜λŠ” woo λ˜λŠ” ma 쀑 ν•˜λ‚˜κ°€ λ§€μΉ˜λœλ‹€.

3. +

  • λ°”λ‘œ μ•žμ˜ νŒ¨ν„΄μ΄ ν•œ 번 이상 반볡될 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
  • 예λ₯Ό λ“€μ–΄, aya, yayaya, wooma, 이런 μ‹μœΌλ‘œ 계속 이어져도 λœλ‹€.
  • 단, 빈 λ¬Έμžμ—΄μ€ μ•ˆ 됨 (그럴 κ²½μš°λŠ” * 써야 함)

4. $

  • λ¬Έμžμ—΄μ˜ 끝을 μ˜λ―Έν•œλ‹€.
  • "^...$" νŒ¨ν„΄μ€ λ¬Έμžμ—΄ 전체가 μ •ν™•νžˆ κ·œμΉ™μ— λ§žμ•„μ•Ό λ§€μΉ˜λ¨μ„ λœ»ν•œλ‹€.

2. μ •κ·œμ‹ 객체 생성

Pattern regex = Pattern.compile(validPattern);

이건 μ •κ·œμ‹ λ¬Έμžμ—΄μ„ μž¬μ‚¬μš© κ°€λŠ₯ν•œ Pattern 객체둜 λ§Œλ“œλŠ” 과정이닀.

  1. Pattern
    • java.util.regex.Pattern 클래슀
    • μ •κ·œμ‹μ„ κ°μ²΄ν™”ν•΄μ„œ μ—¬λŸ¬ 번 μ‚¬μš©ν•  수 있게 λ§Œλ“€μ–΄μ€€λ‹€
    • λ¬Έμžμ—΄μ—μ„œ 반볡적으둜 μ •κ·œμ‹ 맀칭을 ν•˜κ³  싢을 λ•Œ νŽΈλ¦¬ν•˜λ‹€.
  2. compile(String regex)
    • μ •κ·œμ‹ λ¬Έμžμ—΄μ„ Pattern 객체둜 λ³€ν™˜ν•œλ‹€.
    • 예λ₯Ό λ“€μ–΄, μ•„λž˜μ²˜λŸΌ ν•˜λ©΄ pattern μ•ˆμ— μ •κ·œμ‹μ΄ λ“€μ–΄ 있고, λ¬Έμžμ—΄ 검사할 μ€€λΉ„κ°€ 된 것이닀.
String validPattern = "^(aya|ye|woo|ma)+$";
Pattern pattern = Pattern.compile(validPattern);

3. Matcher 와 ν•¨κ»˜ μ‚¬μš©ν•œλ‹€.

for (String b : babbling) {
    // λ§Œμ•½ bκ°€ ν—ˆμš©λœ λ‹¨μ–΄λ‘œλ§Œ 이루어져 있고, μ—°μ†λœ 단어가 μ—†μœΌλ©΄, 카운트λ₯Ό 1 μ˜¬λ¦°λ‹€.
    if (valid.matcher(b).matches() && !invalid.matcher(b).find()) {
        count++;
    }
}
  • 전체 λ¬Έμžμ—΄μ΄ valid νŒ¨ν„΄κ³Ό μΌμΉ˜ν•˜κ³ , 연속 반볡 κΈˆμ§€ λ‹¨μ–΄λŠ” μ—†μœΌλ©΄ β†’ count 증가
  • matches() β†’ 전체 λ¬Έμžμ—΄ 체크
  • find() β†’ λΆ€λΆ„ λ¬Έμžμ—΄ 체크
  • !invalid.matcher(b).find() β†’ 반볡 단어가 μ—†μŒμ„ ν™•μΈν•˜λŠ” 뢀뢄이닀.

1. valid.matcher(b).matches()

  • b λ¬Έμžμ—΄μ΄ ν—ˆμš©λœ 단어("aya", "ye", "woo", "ma")만으둜 이루어져 μžˆλŠ”μ§€ 확인
  • λ¬Έμžμ—΄ 전체가 νŒ¨ν„΄κ³Ό μ™„μ „νžˆ μΌμΉ˜ν•˜λ©΄ true
  • ν•œκΈ€λ‘œ 읽으면 "λ§Œμ•½ bκ°€ aya, ye, woo, ma λ‹¨μ–΄λ“€λ‘œλ§Œ 이루어져 μžˆλ‹€λ©΄"

2. invalid.matcher(b).find()

  • b μ•ˆμ— "ayaaya", "yeye", "woowoo", "mama" 와 같은 단어 반볡이 μžˆλŠ”μ§€ 확인
  • find()λŠ” λΆ€λΆ„ λ¬Έμžμ—΄ 검사
  • !λ₯Ό 뢙이면 반볡 단어가 μ—†μœΌλ©΄ true
  • ν•œκΈ€λ‘œ 읽어보면 "bμ•ˆμ— 같은 단어가 μ—°μ†μœΌλ‘œ λ‚˜μ˜€μ§€ μ•ŠλŠ”λ‹€λ©΄"

3. &&μ΄λ―€λ‘œ μœ„ 1,2 두 쑰건 λͺ¨λ‘ λ§Œμ‘±ν•˜λ©΄ if문이 μ‹€ν–‰λœλ‹€.