알고리즘 CODEKATA 43 (크기가 작은 문자열)

오리너구리·2024년 6월 20일
0

CODEKATA

목록 보기
42/57
post-thumbnail

문제 설명

숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.

예를 들어, t="3141592"이고 p="271" 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.


제한사항

  • 1 ≤ p의 길이 ≤ 18
  • p의 길이 ≤ t의 길이 ≤ 10,000
  • t와 p는 숫자로만 이루어진 문자열이며, 0으로 시작하지 않습니다.

내 풀이

최종코드

class Solution {
    fun solution(t: String, p: String): Int {
        var answer: Int = 0

        for(i in 0 .. t.length-p.length){
            val testNumStr = t.substring(i,i+p.length)
            if(testNumStr.toLong() <= p.toLong()){
                answer++
            }
        }

        return answer
    }
}

풀이과정

class Solution {
    fun solution(t: String, p: String): Int {
        var answer: Int = 0
        
        for(i in 0 .. t.length-p.length){
            val testNumStr = t.slice(i..i+2)
            if(testNumStr.toInt() >= p.toInt()){
                answer++
            }
        }
        
        return answer
    }
}

이렇게 풀까 했는데 이렇게 하는데

인덱스 값으로 마이너스 값을 대입하거나, 문자열 길이보다 큰 인덱스 값을 대입하면 발생한다.

라는 에러가 발생함

i ~i+2 가 10 11 12 가 나온다고함????

0 1 2 나와야하는거아니냐고…..

class Solution {
    fun solution(t: String, p: String): Int {
        var answer: Int = 0
        
        for(i in 0 .. t.length-p.length){
            val testNumStr = t.slice(i..i+p.length-1)
            if(testNumStr.toInt() <= p.toInt()){
                answer++
            }
        }
        
        return answer
    }
}

생각해보니까 +2로 하면 안되고 p의 길이에 따라 인덱스 참조도 다르게 해야할 것같아서 이렇게 바꿨더니 테스트 케이스는 통과해서 채점 돌렸는데

몇 문제에서 런타임 에러가 나버림! ????

그래서 질문하기 탭 보니깐

<P의 길이는 최대 18 이므로 Integer의 범위를 벗어납니다.>

라는 힌트를 발견함

또 너냐 Long?

class Solution {
    fun solution(t: String, p: String): Int {
        var answer: Int = 0
        
        for(i in 0 .. t.length-p.length){
            val testNumStr = t.slice(i..i+p.length-1)
            if(testNumStr.toLong() <= p.toLong()){
                answer++
            }
        }
        
        return answer
    }
}

Int가아니고 Long으로 변환해주니까 성공했당~!


다른 사람 풀이

class Solution {
    fun solution(t: String, p: String): Int {
        return (0..t.length - p.length)
            .map{ t.substring(it until it + p.length) }
            .count { it <= p }
    }
}

이런식으로 아주 간단해보이게 푸신분도 계심

다른 분들은 대충 거의 비슷하게 푸신듯?


subString이랑 slice 차이?

문제 풀때 어떤 확장함수 쓸까 고민하느라 정리해놓은 걸 보다가

slice를 쓸까 subString가 적어논 설명만 보면 뭐가 다르지?

싶어서 둘 다 사용해봤는데 둘 다 이번 문제를 푸는데는 똑같이 작용함.

substring(intRange) → intRange 범위에 속한 문자열 반환

substring(startIndex) → startIndex를 포함하여 index 뒤의 모든 문자열 반환

substring(startIndex,endIndex) → startIndex, endIndex, -1 범위의 문자열 반환

slice(intRange) → 문자열 중에 intRange 범위의 문자열 반환

그래서 굳이 두개로 나눠져있는 이유가있을텐데 하고 찾아봄

subString과 slice의 차이점!

  1. start가 end보다 클 때 (Ex. start 5 , End 0 일 때)

    subString : subString(0,5) 의 결과 리턴

    slice : 빈 문자열 리턴

  2. start가 음수일 때 (Ex. Start -8 , End 10 일 떄)

    subString : subString(0,10) 의 결과 리턴 (음수를 그냥 0으로 처리함)

    slice : slice(3,10) 의 결과 리턴 (문자열 끝에서 앞쪽으로 음수만큼 이동된 인덱스로 처리)

  3. End가 음수일 때 (Ex . Start 0, End-2 일 때)

    subString : subString(0,0) 결과 리턴 (빈문자열) (음수를 0으로 계산)

    slice : slice(0,끝인덱스-2)(문자열 끝에서 앞쪽으로 이동하여 위치를 찾음)

profile
오리너구리입니다

0개의 댓글