[TIL][프로그래머스/Swift] 문자열이 몇 번 등장하는지 세기

Eden·2024년 12월 5일
1

TIL

목록 보기
61/92
post-thumbnail

문제 설명

문자열 myStringpat이 주어집니다. myString에서 pat이 등장하는 횟수를 반환하는 solution 함수를 완성해 주세요.

제한사항

  • 1 ≤ myString의 길이 ≤ 1000
  • 1 ≤ pat의 길이 ≤ 10

입출력 예
| myString | pat | result |
|----------|------|--------|
| "banana" | "ana" | 2 |
| "aaaa" | "aa" | 3 |

처음 쓴 코드

import Foundation

func solution(_ myString: String, _ pat: String) -> Int {
    return myString.components(separatedBy: pat).count - 1
}

간과한 점

  • 이 코드는 패턴이 겹쳐서 등장하는 경우를 제대로 세지 못한다. 예를 들어, "aaaa"에서 "aa"는 중첩되어 등장하는데, components(separatedBy:) 방식은 이러한 경우를 정확하게 다루지 못했다.

두번째 쓴 코드

import Foundation

func solution(_ myString: String, _ pat: String) -> Int {
    var count = 0
    var searchRange = myString.startIndex..<myString.endIndex

    while let range = myString.range(of: pat, options: [], range: searchRange) {
        count += 1
        searchRange = range.upperBound..<myString.endIndex
    }

    return count
}

실수한 점

  • searchRangerange.upperBound로 갱신하면서, 겹치는 패턴을 제대로 찾지 못했다. 예를 들어 "aaaa"에서 "aa"를 찾을 때, 첫 번째 "aa" 이후에 바로 다음 패턴을 찾기 때문에 중첩된 부분을 놓치게 된다.

세번째 쓴 코드

import Foundation

func solution(_ myString: String, _ pat: String) -> Int {
    var count = 0
    var searchRange = myString.startIndex..<myString.endIndex

    while let range = myString.range(of: pat, options: [], range: searchRange) {
        count += 1
        // 패턴이 겹쳐도 찾을 수 있도록 시작점을 한 칸 앞으로 이동
        searchRange = myString.index(after: range.lowerBound)..<myString.endIndex
    }

    return count
}

문제 푸는 방법

  1. 문자열에서 특정 패턴의 등장 횟수를 세는 방법을 고민했다.
  2. 처음에는 components(separatedBy:)를 사용하여 패턴을 기준으로 나누고, 그 조각 수에서 1을 빼는 방식으로 시도했지만, 겹치는 패턴의 경우를 놓쳤다.
  3. 두 번째로는 while 루프와 range(of:)를 사용해 패턴을 찾고 범위를 갱신하면서 반복했으나, 중첩된 패턴을 찾는 데 실패했다.
  4. 마지막으로 range.lowerBound 이후로 검색 범위를 갱신하는 방식으로 수정해, 겹치는 패턴도 모두 찾을 수 있도록 했다.

사용한 문자열 메서드 설명

1. components(separatedBy:)

  • 이 메서드는 문자열을 특정 구분자(여기서는 pat)를 기준으로 나누어 배열로 반환한다. 예를 들어, 문자열 "banana"에서 components(separatedBy: "an")을 사용하면 ["b", "a", "a"]라는 배열이 반환된다. 이 방법은 간단하지만, 중첩된 패턴을 찾는 데에는 한계가 있다.

2. range(of:options:range:)

  • 이 메서드는 주어진 문자열에서 특정 패턴의 첫 번째 범위를 찾고, 그 범위를 반환한다. optionsrange 매개변수를 통해 검색 방식과 범위를 조정할 수 있다. 예를 들어, 문자열 "banana"에서 range(of: "ana")를 사용하면 첫 번째 "ana"의 범위를 반환한다.

3. index(after:)

  • 이 메서드는 문자열에서 주어진 인덱스 바로 다음 위치의 인덱스를 반환한다. 이를 이용해 겹치는 패턴을 검색할 때 시작 위치를 한 칸 앞으로 이동할 수 있다.

배운 점

  • 문자열에서 패턴을 찾을 때, 겹치는 패턴이 있는 경우를 고려해야 한다는 점을 배웠다.
  • range(of:)index(after:)를 사용해 문자열을 탐색하고, 범위를 적절히 조정하여 모든 패턴을 찾는 방법을 익혔다.
  • 문제 해결을 위해 다양한 접근 방식을 시도하고, 실패한 부분을 분석해 개선하는 과정의 중요성을 느꼈다.
profile
Frontend🌐 and iOS

0개의 댓글