문자열을 정수로 변환하는 atoi 모듈을 설계해야 한다고 가정해 봅시다. 이 모듈은 먼저 불필요한 공백 문자를 모두 건너뛰어 첫 번째 비공백 문자에 도달한 뒤, 해당 문자부터 선택적인 부호(+ 또는 -)와 그 뒤에 이어지는 숫자들을 읽어 하나의 수치 값으로 해석합니다.
만약 문자열에서 발견된 첫 번째 비공백 문자 시퀀스가 유효한 정수가 아니거나, 문자열이 비어 있거나 공백만으로 이루어져 변환할 시퀀스 자체가 없다면 변환은 수행되지 않습니다.
예를 들어 입력이 "-45"라면 출력은 -45가 됩니다.
해결 접근 방법
이 문제는 다음 단계를 따라 해결할 수 있습니다.
sign = 1,base = 0,i = 0으로 초기화하고,n은 문자열s의 길이로 설정합니다.i < n이고s[i]가 공백인 동안i를 1씩 증가시켜 선행 공백을 건너뜁니다.- 첫 번째 유효 문자가
-라면sign = -1,+또는 숫자라면sign = 1로 설정합니다. s[i]가'0'부터'9'범위에 있는 동안 각 문자를 읽어 정수로 변환하고, 기존base값에 10을 곱한 뒤 새 숫자를 더하는 방식으로 누적 계산합니다.- 최종적으로
base * sign을 반환합니다.
오버플로우 처리
32비트 정수 범위를 벗어나는 경우를 대비해 오버플로우 검사가 반드시 필요합니다. 새로운 숫자를 더하기 전에 base가 INT_MAX / 10보다 크거나, 같으면서 다음 자릿수가 INT_MAX % 10보다 크면 범위를 초과하게 됩니다. 이때 부호가 양수면 INT_MAX를, 음수면 INT_MIN을 반환하도록 처리합니다.
C++ 구현 예제
아래 구현 예제를 통해 더 자세히 이해해 보겠습니다.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int myAtoi(string str) {
int sign = 1;
int base = 0;
int i = 0;
int n = str.size();
while(i < n && str[i] == ' '){
i++;
}
if(str[i] == '-' || str[i] == '+') sign = 1 - 2*(str[i++] =='-');
while(str[i] >= '0' && str[i] <='9'){
if(base > INT_MAX/10 || base == INT_MAX/10 && str[i]- '0' > INT_MAX %10){
if(sign == 1)return INT_MAX;
return INT_MIN;
}
base = (base * 10) + (str[i++] - '0');
}
return base * sign;
}
};
main(){
Solution ob;
cout << ob.myAtoi("-45")<<endl;
cout << ob.myAtoi(" 56")<<endl;
cout << ob.myAtoi("100")<<endl;
}입력
"-45" " 56" "100"
출력
-45 56 100
실행 결과를 보면 선행 공백이 있는 " 56"도 올바르게 56으로 변환되고, 음수 문자열 "-45"는 -45로 정확히 변환되는 것을 확인할 수 있습니다.