[프로그래머스]크기가 작은 부분 문자열 - 파이썬

Donghyun·2024년 7월 1일
0

Code Kata - 파이썬

목록 보기
2/54
post-thumbnail

링크: https://school.programmers.co.kr/learn/courses/30/lessons/147355

문제 설명

숫자로 이루어진 문자열 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으로 시작하지 않습니다.

입출력 예

tpresult
"3141592""271"2
"500220839878""7"8
"10203""15"3

입출력 예 설명

입출력 예 #1

본문과 같습니다.

입출력 예 #2

p의 길이가 1이므로 t의 부분문자열은 "5", "0", 0", "2", "2", "0", "8", "3", "9", "8", "7", "8"이며 이중 7보다 작거나 같은 숫자는 "5", "0", "0", "2", "2", "0", "3", "7" 이렇게 8개가 있습니다.

입출력 예 #3

p의 길이가 2이므로 t의 부분문자열은 "10", "02", "20", "03"이며, 이중 15보다 작거나 같은 숫자는 "10", "02", "03" 이렇게 3개입니다. "02"와 "03"은 각각 2, 3에 해당한다는 점에 주의하세요

문제 풀이

  1. t 에서 만들 수 있는 부분문자열 중 p 의 길이와 같은 것 뽑기
  2. 이 조합들 중에서 p 와 크기가 작거나 같은 것의 갯수 return 하기.

여기서 문제는 p 의 길이가 다 제각각이라 바로 전 문제에서 했던 for 문 세 개 중첩해서 하는 방식이 안 통하기 때문에 이 조합을 어떻게 만드냐는 것이었다.

  • 그래서 문제설명을 천천히 읽어보던 중 예시 ‘3141592’ 에서의 부분 문자열은 314, 141, 415, 159, 592 라는 것을 보고 부분문자열을 찾아봤더니,
  • 부분문자열: 문자열의 연속된 일부. 문자열이 연속되어야 한다는 것!

그러면 이제 문자열 슬라이싱을 이용해서 간단하게 코드를 만들 수 있을거 같다

    for i in range(len(t) - len(p)):
        if int(t[i:len(p)+i]) <= int(p):
            result += 1

하지만 이렇게 했을 때 실행결과 1, 2 는 통과했지만 3 에서 오답이 발생했다. 왜일까?

  • 각 반복 마다 어떻게 시행되고 있는지 살펴봤다.
  • t = 3141592, p = 271
    • t[0:3] → 314
    • t[1:4] → 141
    • t[2:5] → 415
    • t[3:6] → 159
  • 아뿔싸… 충분한 범위를 검사하지 못해 일부 문자열을 놓치고 있었는데 운이 좋게도 예시 1, 2번의 놓친 부분문자열이 p 보다 컸기 때문에 정답이 된 것이다.

최종코드

그래서 다음과 같이 range 를 수정했을 때 잘 해결되는 것을 확인할 수 있었다.

def solution(t, p):
    result = 0

    for i in range(len(t) - len(p)+1):
        if int(t[i:len(p)+i]) <= int(p):
            result += 1

    return result
profile
데이터분석 공부 일기~!

0개의 댓글