관리 메뉴

나만을 위한 블로그

[Algorithm] 프로그래머스 - 문자열 겹쳐쓰기 (Kotlin) 본문

알고리즘 문제 풀이/프로그래머스

[Algorithm] 프로그래머스 - 문자열 겹쳐쓰기 (Kotlin)

참깨빵위에참깨빵_ 2023. 12. 2. 22:04
728x90
반응형
문자열 my_string, overwrite_string과 정수 s가 주어진다. 문자열 my_string의 인덱스 s부터 overwrite_string의 길이만큼을 문자열 overwrite_string으로 바꾼 문자열을 리턴하는 함수를 작성하라

 

 

갑자기 문제 난이도가 매워진다. 일단 문제가 정확히 뭘 요구하는지부터 확인한다.

입출력 예를 보면 my_string의 2번 인덱스부터 overwrite_string을 덮어씌우라는 것이다. 만약 my_string이 overwrite_string보다 길다면, overwrite_string 뒤의 기존 문자열은 유지된다.

1번 예시를 보면 my_string의 2번 인덱스부터의 문자열을 "lloWorl"로 바꿨는데, 마지막 문자인 "d"는 그대로 유지되고 있는 걸 볼 수 있다.

 

문제 해결은 여러 방법으로 할 수 있지만 난 아래와 같이 풀었다.

 

// solution("He11oWor1d", "lloWorl", 2)

fun solution(my_string: String, overwrite_string: String, s: Int): String {
    val answer = StringBuilder()
    val overwriteStrLen = overwrite_string.length
    val myStrLen = my_string.length
    answer.append(my_string.substring(0, s)) // He
        .append(overwrite_string) // lloWorl
        .append(my_string.substring(s + overwriteStrLen, myStrLen)) // d

    return answer.toString()
}

 

최대 길이가 1,000개인 문자열을 받기 때문에, 문자열 조작이기 때문에 StringBuilder를 써서 리턴시킬 문자열을 만든다.

그리고 solution()의 1번, 2번 매개변수로 받은 문자열 길이를 구한다. 그래야 어느 위치부터 overwrite_string을 붙이고, 어느 위치부터 기존 문자열을 새 문자열(overwrite_string이 붙은 문자열) 뒤에 이어붙일지 알 수 있기 때문이다.

 

각 append() 뒤에 주석으로 append()가 호출된 뒤에 어떤 문자열이 붙을지 써놨다.

1번째 append()가 끝나면 1번째 매개변수의 문자열을 0번~2번 인덱스 이전까지 자른 결과인 "He"가 남는다.

2번째 append()가 끝나면 solution()의 2번째 매개변수를 1번째 append() 결과 뒤에 이어붙이기 때문에 "HelloWorl"가 될 것이다. 이 부분이 문제의 핵심이기도 하다.

3번째 append는 s와 overwrite_string의 길이를 더한다. 그래야 이어붙인 문자열만큼의 길이를 구하고, overwrite_string으로 바뀌지 않은 나머지 문자열을 추가할 수 있다. 1번 입출력 예시를 사용하면 "HelloWorld"에서 "HelloWorl"이 사라지고, "d"만 남기 때문에 "d"가 마지막으로 이어붙여진다.

 

이 풀이를 사용하면 최소 0.02초, 최대 0.04초 안으로 테스트 케이스 검사가 통과된다. StringBuilder의 덕분인 것으로 생각된다.

하지만 코틀린이 제공하는 문자열 관련 함수를 쓰면 더 간단하게 이 문제를 풀 수 있다.

 

fun solution(my_string: String, overwrite_string: String, s: Int): String =
    my_string.replaceRange(s, s + overwrite_string.length, overwrite_string)

 

코틀린 공식문서에서 설명하는 replaceRange() 함수는 아래와 같다.

 

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/replace-range.html

 

replaceRange - Kotlin Programming Language

 

kotlinlang.org

fun CharSequence.replaceRange(
    startIndex: Int,
    endIndex: Int,
    replacement: CharSequence
): CharSequence
(source)
이 문자 시퀀스의 내용이 포함된 문자 시퀀스를 리턴한다. 여기서 해당 범위의 부분은 대체 문자 시퀀스로 바뀐다

- startIndex : 교체할 첫 번째 문자의 인덱스
- endIndex : 문자열에서 유지할 교체 후 첫 번째 문자의 인덱스

 

그렇다면 비슷한 문제가 나올 때마다 이 replaceRange()를 쓰면 될까? 이건 좀 더 고려해봐야 한다.

왜냐면 replaceRange()를 써서 문제를 제출하면, 내 경우 테스트 케이스 별 통과까지 최소 6초, 최대 10초까지 걸린다.

 

 

반면 좀 복잡하더라도 StringBuilder를 쓰면 최소 0.02초, 최대 0.05초까지 걸린다.

 

 

1,000개의 문자열을 다루기 때문에 이 정도고 만약 100만 개 이상의 문자열을 다뤄야 한다면 성능 차이는 더 현격하게 벌어질 것은 분명하다. 선택은 본인 몫

반응형
Comments