[프로그래머스 | Swift | Lv.0] 문자열 겹쳐쓰기

Juhee Kim·2025년 4월 2일
0

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


풀이 1: 오류

import Foundation

func solution(_ mystring:String, * overwrite*string:String,  s:Int) -> String {
    let firstIdx = my_string.index(my_string.startIndex, offsetBy: s) // 덮어쓰기 시작 인덱스
    var result = String(my_string[..<firstIdx]) + overwrite_string // 덮어쓴 문자열
    
    guard let lastIdx = my_string.index(my_string.startIndex, offsetBy: s + overwrite_string.count) {
        result += String(my_string[lastIdx]...)   
    } // 덮어쓰고 남은 원본 문자열을 result에 추가
    
    return result
}

문제점

  • guard let 구문의 잘못된 사용:
    index(startIndex, offsetBy:) 메서드는 옵셔널 값을 반환하지 않는다. 따라서 guard let으로 처리할 필요가 없다.
    만약 요청한 인덱스가 문자열 범위를 벗어나면 이 메서드는 nil을 반환하는 것이 아니라 런타임 오류를 발생시킵니다.

  • 슬라이싱 문법 오류:
    my_string[lastIdx]...에서 lastIdx는 인덱스이지만, 범위 연산자를 사용하려면 my_string[lastIdx...]와 같이 작성해야 한다.


풀이 2: 오류

import Foundation

func solution(_ mystring:String, * overwrite*string:String,  s:Int) -> String {
    let firstIdx = my_string.index(my_string.startIndex, offsetBy: s) // 덮어쓰기 시작 인덱스
    let lastIdx = my_string.index(my_string.startIndex, offsetBy: s + overwrite_string.count) // 덮어쓰기 마지막 인덱스 + 1
    
    var result = String(my_string[..<firstIdx]) + overwrite_string
    if my_string.count >= Int(lastIdx)  { // 남은 원본 문자가 있으면 결과 문자열에 추가
        result += String(my_string[lastIdx...])   
    }
    return result
}

문제점

  • 타입 변환 오류:
    if my_string.count >= Int(lastIdx) 부분에서 lastIdxInt로 변환하려고 시도했다. 그러나 lastIdxString.Index 타입이으로 정수형으로 직접 변환할 수 없다.

  • 불필요한 조건 검사:
    문제의 제한사항에 따르면 s + overwrite_string.count는 항상 my_string.count 이하임이 보장된다. 따라서 이 조건 검사는 불필요하다.

    💡 항상 lastIdxmy_string의 범위를 벗어나지 않는 이유?
    my_string.endIndex문자열의 길이와 같다 (즉, my_string.count와 동일한 위치).
    따라서 제한사항에 의해 s + overwrite_string.count(덮어쓰기 마지막 인덱스 + 1) ≤ my_string.count가 보장되므로, lastIdx ≤ my_string.endIndex도 항상 성립한다.


풀이 3

import Foundation

func solution(_ my_string:String, _ overwrite_string:String, _ s:Int) -> String {
    let firstIdx = my_string.index(my_string.startIndex, offsetBy: s) // 덮어쓰기 시작 인덱스
    let lastIdx = my_string.index(my_string.startIndex, offsetBy: s + overwrite_string.count) // 덮어쓰기 마지막 인덱스 + 1
    
    let result = String(my_string[..<firstIdx]) + overwrite_string + String(my_string[lastIdx...])  

    return result
}

설명

  1. 덮어쓰기 시작할 인덱스 이전까지는 원본 문자열을 저장한다.
  2. 덮어쓰기 시작할 인덱스부터 덮어쓸 문자열의 끝까지를 저장한다.
  3. 남은 원본 문자열을 저장한다. (혹은 남은 문자열이 없거나)

다른 사람의 풀이

import Foundation

func solution(_ myString: String, _ overwriteString: String, _ s: Int) -> String {
    var myString = Array(myString)
    myString.replaceSubrange(s...(overwriteString.count+s-1), with: Array(overwriteString))
    return String(myString)
}

설명

  • 문자열을 문자 배열로 변환: var myString = Array(myString)
    원본 문자열을 [Character] 타입의 배열로 변환 → Swift의 정수 인덱싱을 사용할 수 있어 작업이 단순해짐

  • 부분 범위 교체:
    replaceSubrange 메서드는 배열의 특정 범위를 다른 요소들로 교체한다.
    범위 지정은 다음과 같다.
    시작: s (정수 인덱스)
    : overwriteString.count+s-1 (덮어쓸 문자열의 길이를 고려한 마지막 인덱스)
    ...는 끝 인덱스를 포함하는 닫힌 범위를 만든다.
    Array(overwriteString)는 덮어쓸 문자열도 문자 배열로 변환한다.

  • 결과 변환 및 반환:
    수정된 문자 배열을 다시 String으로 변환하여 반환


알게 된 것 정리

  • my_string.index(my_string.startIndex, offsetBy: s)
    Int 인덱스 값으로 String.index 값 얻기

  • myString.replaceSubrange(s...(overwriteString.count+s-1), with: Array(overwriteString))
    원본 배열의 a번 째부터 b번 째의 요소를 with 배열의 요소로 교체

  • 문자열은 Character 배열로 변경해서 다루면 편리할 때가 있다.

profile
개: 개롭지만 발: 발전하는중

0개의 댓글

관련 채용 정보