(알고리즘) 옹알이

2024. 5. 25. 09:00TIL

신나는 주말!

주말에는 간단한 알고리즘 문제를 풀어보자!

 

🔥알고리즘 문제

문제 설명

머쓱이는 태어난 지 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", "uuu", "yeye", "yemawoo", "ayaayaa"]에서 발음할 수 있는 것은 "aya" + "ye" = "ayaye", "ye" + "ma" + "woo" = "yemawoo"로 2개입니다. "yeye"는 같은 발음이 연속되므로 발음할 수 없습니다. 따라서 2를 return합니다.

 

유의사항

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

 

내가 작성한 코드 

fun solution(babblings: Array<String>): Int {
    val canSay = listOf("aya", "ye", "woo", "ma")
    var answer = 0

    babblings.forEach {
        var bab = it

        if (!it.checkingDuplicatedWords(canSay)) {
            canSay.forEach { canSpeakWord ->
                bab = bab.replace(canSpeakWord, "★")
            }

            if (bab.all{it.toString()=="★"}) answer++
        }
    }

    return answer
}

fun String.checkingDuplicatedWords(words: List<String>): Boolean {
    words.forEach {
        keyword ->
        if (this.contains(keyword + keyword)) return true

    }

    return false
}

 

내가 작성한 코드 해석

동일한 발음의 문자열이 연속해서 오면 안되므로 checkingDuplicatedWords라는 함수를 생성해서 동일한 문자가 연속해서 오게되면 false를 반환하게 함


if (!it.checkingDuplicatedWords(canSay))​

동일한 문자가 연속적으로 오지않은경우에 해당 조건문이 참


canSay.forEach { canSpeakWord -> bab = bab.replace(canSpeakWord, "★")}​

canSay의 각 요소들  "aya",  "ye",  "woo",  "ma" 이 4개의 각 요소들이 사용자로부터 입력받은 babblings 배열에 자신이 해당하는 값들에 로 대체되어짐 

즉) 예를들어 babblings가 ("ayaye", "uuu", "yeye", "yemawoo", "ayaayaa") 라면 ("★★", "uuu",  "yeye", "★★★",  "ayaayaa") 로 바뀌어짐


if (bab.all{it.toString()=="★"}) answer++​

 

따라서 로만 이루어진 요소가 있다면 answer의 값을 1증가시킨다


return answer​

결과값 반환

 

 

다른사람은 어떻게 했을까?

fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        var regex = "aya|ye|woo|ma".toRegex()
        var regexC = "ayaaya|yeye|woowoo|mama".toRegex()
        answer = babbling.map{it.replace(regexC,"*")}.map{it.replace(regex,"")}.filter { it =="" }.size
        return answer
    }
   //Valentine , ㅎㄹ님의 코드입니다

 

다른 사람들이 작성한 코드 해석

var regex = "aya|ye|woo|ma".toRegex()​

문자열  "aya|ye|woo|ma"에 해당하는 정규 표현식 객체를 생성.
이 정규 표현식은 "aya","ye","woo","ma" 중 하나를 나타냄


var regexC = "ayaaya|yeye|woowoo|mama".toRegex()​

문자열 "ayaaya|yeye|woowoo|mama"에 해당하는 정규 표현식 객체를 생성.
이 정규 표현식은 "ayaaya", "yeye", "woowoo", "mama" 중 하나를 나타냄


babbling.map{it.replace(regexC,"*")}

babbling의 각 요소에대해서 정규표현식 regexC 에 해당하는 부분을 "*"로 대체함. 즉 "ayaaya", "yeye", "woowoo", "mama" 에 해당하는 부분이 있다면 *로 대체한다


.map{it.replace(regex,"")}

 "ayaaya", "yeye", "woowoo", "mama" 에 해당하는 부분이 *로 대체된 상태에서  "aya","ye","woo","ma" 에 해당하는 요소들을 "" 공백으로 대체함. 

.filter { it =="" }.size

*이나 공백으로 대체된 각 요소들중에서  공백인 요소들의 개수를 반환함


answer = babbling.map{it.replace(regexC,"*")}
.map{it.replace(regex,"")}
.filter { it =="" }.size

공백인 요소들의 개수를 answer에 저장

return answer

answer 반환

헉! 다른사람들은 이렇게 쉽게....

 

 

더 개선해야할 Point

toRegex() 를 통해서 생성된 정규 표현식 객체는 여러 메서드를 사용할 수 있다

 matches() 전체 문자열이 정규 표현식에 매칭되는지 true false 반환

containsMatchln() 문자열 내에 정규 표현식과 매칭되는 부분이 있는지 true false 반환

find() 문자열 내에서 정규 표현식과 매칭되는 첫번째 부분을 반환

findAll()  문자열 내에서 정규 표현식과 매칭되는 모든 부분을 반환

replace() 정규표현식과 매칭되는 부분을 다른 문자열로 대체

toRegex()함수에 더 친숙해져야겠다!

 

알고리즘 GitHub : https://github.com/kotlin2024/algorithm/commit/c06871efa905027517125b533c01045d8ec421ba#diff-37039b5113987b496177f4e59ed4f8e6a596a75c09ce844d8a984fb93b12cfb3