본문 바로가기

알고리즘/LeetCode

String to Integer (atoi)

LeetCode의 String to Integer (atoi) 문제다.

 

String to Integer (atoi) - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

단순히 주어진 문자열을 정수로 변환하는 것이 목적인데 파이썬에서는 그냥 int() 메서드로 문자열을 정수로 변환할 수 있다. 하지만 메서드의 매개변수로 전달되는 문자열은 올바른 문자열이어야 하기 때문에 문제에서 주어진 문자열을 필터링하는 과정이 필요하다.

 

문제에서 요구되는 조건은 다음과 같다.

  • 문자열의 시작(leading) 공백은 무시해야 한다.

  • 문자열이 '+', '-' 기호로 시작한다면 그에 맞게 양수, 음수로 변환해야 한다.

  • 문자는 끝까지 읽거나 숫자가 아닌 문자를 읽을 때까지 읽어서 변환해야 한다. 이후 문자들은 무시된다.

  • 남은 문자열이 없다면 0을 반환한다.

  • 변환된 정수가 정수형(-2^31 ~ 2^31 - 1)을 초과한다면 범위의 최댓값 또는 최솟값으로 낮춘다(clamp).

숫자 문자열을 파싱 하려면 거의 기본적으로 요구되는 사항들일 것이다. 여기서 유의해야 할 것은 필터링 과정을 거치고 남은 문자열이 없을 경우 0을 반환해야 한다는 것이다. 그 부분만 신경 써준다면 나머지는 파이썬의 슬라이싱과 문자열 메서드를 이용하여 어렵지 않게 구현할 수 있다.

class Solution:
    def myAtoi(self, s: str) -> int:
        is_negative = False
        s = s.strip()
        
        # 문자열이 비어있다면 종료
        if len(s) < 1:
            return 0
        
        # 양수, 음수 구분
        if s[0] == '-':
            is_negative = True
            s = s[1:]
        elif s[0] == '+':
            is_negative = False
            s = s[1:]
            
        # 정수 문자가 아닌 문자의 위치를 파악    
        non_digit_index = -1
        for index, character in enumerate(s):
            if character.isdigit() == False:
                non_digit_index = index
                break
        
        # 해당 문자까지만 정수 문자열로 분리
        if non_digit_index > -1:
            s = s[:non_digit_index]
            
        # 정수 문자열이 없다면 반환    
        if len(s) < 1:
            return 0
        
        # 제한 설정, 자연수 변환
        upper_limit = 2 ** 31 - 1
        lower_limit = 2 ** 31 * -1
        converted_value = int(s) * (-1 if is_negative else 1)
        
        # clamp
        if converted_value > upper_limit:
            return upper_limit
        elif converted_value < lower_limit:
            return lower_limit
        else:
            return converted_value

먼저 공백을 제거하고 남은 문자열이 없다면 공백 문자열만 주어진 것이기 때문에 0을 반환한다. 그렇지 않다면 계속 필터링을 진행하며 부호 문자 파싱, 정수 문자열만 추출, 변환, 축약(clamp)하는 과정을 거치는 간단한 로직이다. 정수 문자열 뒤에 일반 문자열이 더 있을 수 있다는 예외를 놓쳐서 몇 번 틀렸던 기억이 있다.

 

"abcd42" 같은 건 42로 변환할 수 없지 않나? 싶지만 문제에서는 문자를 뛰어넘어서 파싱 하는 것을 요구하고 있지 않기 때문에 위처럼 구현하였다.

 

 

아마 자바나 C언어였다면 코드가 좀 더 복잡해졌을 텐데 파이썬으로 처리하니 쉽게 구현할 수 있었다. 역시 이런 점에서는 파이썬의 강점이 드러나는 것 같다. 특히 C언어로 문자열을 다루던 때를 생각하면 이젠 어떻게 해야 할지 기억도 나지 않는다.

'알고리즘 > LeetCode' 카테고리의 다른 글

Group Anagrams  (0) 2021.02.17
Most Common Word  (0) 2021.02.17
Reorder Data in Log Files (Sort)  (0) 2021.02.16
Binary Tree Level Order Traversal (Queue)  (0) 2021.02.16
Binary Tree Postorder Traversal (Stack)  (0) 2021.02.16