프로그래밍/코딩테스트

[실수 분석] 2021 카카오 인턴 3번, 문자열

turu 2021. 5. 10. 19:45

제목: [실수 분석] 2021 카카오 인턴 3번, 문자열  

단순 구현 문제였다.  

정확도는 통과가 되었지만, 효율성에서 반타작이 나왔다.

다른 사람 후기를 보아도 비슷하게 푼 것 같아 계속 원인을 찾아보다가 실수한 부분을 찾았다.

 

(2021. 5. 15 수정)

처음에는 split, component 메서드부분이 원인이라고 생각했지만,

다른 분과 이야기를 하면서 이 부분은 메서드 변경할때마다 성능차이가 나는정도의 성능향상이라면 큰 의미가 없는것 같다고 판단되었다.

커서가 100만개의 첫부분과 맨끝부분을 계속 이동하게 될 때 문제를 해결하는 방향으로 해결해야 했던 것 같다..

즉 세그먼트 트리, 펜윅 트리 + 이진탐색 등으로 커서 위치를 이동하는 부분을 해결해야 했던 것 같다.

 

(2021. 12. 22  수정)

세그먼트 트리 같은 알고리즘을 사용하지 않아도 이중연결리스트로 풀면 되는 문제였다.

 

도중에 테스트한 결과는 아래와 같다.

[split, component, String index접근에 각각 걸리는 시간 비교]

component: 3914.0666246414185 ms
String index분리: 2102.8331756591797 ms
split: 3291.561245918274 ms

걸린시간은 component > split > index분리 순으로 오래걸렸다.

 

아래 부터는 split, component 메서드부분이 원인이라고 생각했을 때 쓴 내용을 남겨둔다.


 

 

하나의 문자열을 여러개의 문자열로 분리하는 부분이 오래 걸리는게 원인이었는데,

 

예) 문자열 "U 12345" 을 각각  ["U", "12345"] 으로 분리해야 하는 상황

위 상황에서는 공백(" ") 이 단 1번만 나오는 경우라서

components<>(separatedBy:) 대신 다른 방법으로 구현하는게 더 효율적이었던 것이었다.

아마 components<>(separagtedBy:)로 구현한거였으면 원소 전체를 순회해야하니 O(n)이 필요했을 것이다.

 

위 문제의 부분을 아래처럼 수정했다.

// operation은 String
///  수정전
let split = operation.components(separatedBy: " ")
let op = split[0]
let n = Int(split[1])!
  
/// 수정후
let start = operation.index(operation.startIndex, offsetBy: 2)
let range = start..<operation.endIndex
let op = operation[operation.startIndex]
let n = Int(operation[range])!

 

수정한 후, 실행시간은 아래처럼 약 50% 단축되었다...ㅠㅠ

 

 

 

실수한 원인:

 

문자열을 다루는게 익숙하지 않아서 몇몇 강력한 메소드에 의존하던게 원인이었던 것 같다.

자주써버리는 메서드에 대해서 알아두는게 필요한 것 같다.

반응형