LeetCode 8번 String to Integer / atoi 함수 구현

이번 문제는 문자열을 정수로 바꾸는 함수, 프로그래밍 해본 사람이라면 한번 쯤은 사용해봤을만한 atoi 함수를 구현하는 것이 목표라 할 수 있다.

그만큼 기본적이라 할 수 있는데, 생각할 테스트케이스가 많아서 단순하지만은 않다고 생각한다.

 

# 문제

간단히 말해서 문자열을 정수로 만드는 함수를 만드는 것이다.

이 함수는 처음으로 빈 공백이 아닌 문자를 찾을 때까지 모든 공백을 취급하지 않는다. 그 후, 문자는 초기의 '+' 또는 '-' 를 선택하고, 가능한의 숫자를 취급한다.

 

문자열은 숫자 이후의 문자열이 포함될 수 있으나, 그 숫자를 취할 수는 없다. 즉, 숫자와 숫자 사이의 다른 문자가 들어가면 뒤의 숫자는 버린다는 뜻이다.


유효하지 않은 숫자라면 0을 반환한다.


# 해결한 코드 (초안, 거의 통과하기 위한 주먹구구식 코드) 

아래 코드는 문제를 제대로 읽지 않고 혼자 테스트케이스를 생각하면서 구현한 코드이다. 그로 인해 중간 부분에 if문을 남발한 부분이 있고, 전체적으로 코드가 쓸데 없이 산만해 보인다.

 

# 문제를 어떻게 접근했나

처음엔 굉장히 쉬운 문제라 생각했다. 왜 이 문제가 medium 난이도에 15.5퍼센터의 성공률일까 생각했는데, 하다보니 까다롭다고 생각이 들었다. (물론, 이건 문제를 제대로 읽지 않아서 그런 것이었음. 문제를 읽어보면 피해야할 조건을 어느정도 회피할 수 있을 듯)

 

그래서 단순히 부호가 나올 경우 취하고, 이후의 숫자가 나오면 값을 저장해서 부호와 함께 출력되도록 구현했다.

그랬더니, 마지막 예제에서 걸렸다. 그 이유는 정수의 범위를 넘어서였다. 그렇다고 더 큰 타입을 사용하는 건 문제의 의도가 아닐 것으로 생각하였고, 이를 코드 90~113처럼 풀었다.

즉, int의 범위는 -2147483648 ~ 2147483647이다. 이를 넘기면 runtime error: signed integer overflow: ~~ cannot be represented in type 'int' 라는 문구가 발생한다. 그러므로, 아래처럼 조건을 정하여 해결하였다.

1. 숫자의 길이가 10자리보다 크면 부호에 따라 최대값 또는 최소값으로 치환한다.

2. 숫자이 길이가 10자리면 입력 값보다 클 경우에는 최대값, 작을 경우에는 최소값으로 치환한다.

3. 그 외에는 숫자 그대로를 사용한다.


다음 문제는 테스트 케이스들을 통과하는 것이었다. 생각보다 다양한 테스트케이스가 존재하였다.

위에서도 말했지만, 이건 문제를 제대로 읽지 않아서 발생한 문제기도 했다. (뭐랄까, 영문 영어는 읽기 귀찮아서 그런 것 같다..)  예제 외의 테스트케이스로는 크게 아래와 같다.

1. '+-' 부호가 동시에 있는 경우. ex) +-2022

보통 부호가 연속으로 있으면 그러려니 하고 계산했었는데, 이 문제에서는 잘못된 숫자로 생각 해야 한다.

2. 연속되는 숫자가 나오는 경우

예를 들면 "0000-61a1223"를 말한다. 내 생각으론 답이 -61이어야 한다고 생각했는데, 앞에 0이 있으므로 답은 0이고 이후의 숫자는 무시해야 한다.

3. 숫자와 숫자 사이에 공백이 있는 경우

예를 들면 " +0 595"를 말한다. 이 경우도 중간에 공백이 있다. 그러므로, 앞에 숫자만 취해야 한다고 생각하면 된다. 다만, 공백을 허용한다길래 답이 595인 줄 알았기 때문에 통과를 하지 못했다.


# 결론

그래도 런타임 속도는 빠른 것에 의미를 두어야 하나.. 라고 자기 위안을 한다.

 

아무튼, 정리해보니 문제를 제대로 읽지 않은게 가장 큰 문제로 보인다. 문제 자체는 쉽기 때문이다. 이후에 문제를 다시 풀어보고, 실제 atoi가 어떻게 구현 되어 있는 지도 확인해보면 좋을 것 같다.






댓글