LeetCode 8: Cadena a entero (atoi)

Nov 13 2020

Estoy publicando una solución para "String to Integer (atoi)" de LeetCode. Si desea revisarlo, hágalo. ¡Gracias!

Problema

Implemente atoi que convierte una cadena en un número entero. La función primero descarta tantos caracteres de espacio en blanco como sea necesario hasta que se encuentra el primer carácter que no es de espacio en blanco. Luego, a partir de este carácter se toma un signo más o menos inicial opcional seguido de tantos dígitos numéricos como sea posible, y los interpreta como un valor numérico. La cadena puede contener caracteres adicionales después de los que forman el número entero, que se ignoran y no tienen ningún efecto en el comportamiento de esta función. Si la primera secuencia de caracteres que no son espacios en blanco en str no es un número entero válido, o si tal secuencia no existe porque str está vacía o contiene solo caracteres de espacio en blanco, no se realiza ninguna conversión. Si no se pudo realizar una conversión válida, se devuelve un valor cero.

Nota:

Solo el carácter de espacio '' se considera un carácter de espacio en blanco. Suponga que estamos tratando con un entorno que solo podría almacenar enteros dentro del rango de enteros con signo de 32 bits: [−231, 231 - 1]. Si el valor numérico está fuera del rango de valores representables, se devuelve 231 - 1 o −231.

Ejemplo 1:

Input: str = "42"
Output: 42

Ejemplo 2:

Input: str = "   -42"
Output: -42
Explanation: The first non-whitespace character is '-', which is the minus sign. Then take as many numerical digits as possible, which gets 42.

Ejemplo 3:

Input: str = "4193 with words"
Output: 4193
Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.

Ejemplo 4:

Input: str = "words and 987"
Output: 0
Explanation: The first non-whitespace character is 'w', which is not a numerical digit or a +/- sign. Therefore no valid conversion could be performed.

Ejemplo 5:

Input: str = "-91283472332"
Output: -2147483648
Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer. Thefore INT_MIN (−231) is returned.

Código

from typing import List
import collections
import itertools
import functools
import math
import string
import random
import bisect
import re
import operator
import heapq
import queue

from queue import PriorityQueue
from itertools import combinations, permutations
from functools import lru_cache
from collections import defaultdict
from collections import OrderedDict
from collections import deque
from collections import Counter


class Solution:
    def myAtoi(self, s):
        s = re.findall(r'^\s*[+-]?\d+', s)
        try:
            MAX, MIN = 2147483647, -2147483648
            res = int(''.join(s))
            if res > MAX:
                return MAX
            if res < MIN:
                return MIN
            return res
        except:
            return 0


if __name__ == "__main__":
    print(Solution().myAtoi("   -42"))

Referencias:

  • LeetCode 8. Cadena a entero (atoi)

  • Leetcode atoi (cadena a entero)

Respuestas

3 Marc Nov 13 2020 at 10:21

Buena solución, es compacta y fácil de entender. Hay poco que mejorar, pocas sugerencias:

  • Importaciones : hay muchas importaciones, tal vez sobras de intentos anteriores.
  • Try Except block : debe estar alrededor del código que puede causar la excepción.

Aplicando las sugerencias:

import re

class Solution:
    def myAtoi(self, s: str) -> int:
        MAX, MIN = 2147483647, -2147483648
        s = re.findall(r'^\s*[+-]?\d+', s)
        try:
            res = int(''.join(s))
        except:
            return 0
        if res > MAX:
            return MAX
        if res < MIN:
            return MIN
        return res

Actuación

Runtime: 36 ms, faster than 51.56% of Python3 online submissions
Memory Usage: 14.1 MB, less than 32.27% of Python3 online submissions

Regex hace que el código sea compacto pero no es el enfoque más rápido. Las soluciones más rápidas recorren la cadena carácter a carácter.

1 Reinderien Nov 13 2020 at 22:22

Números mágicos

2147483647, -2147483648

son en realidad

1<<31 - 1, -(1<<31)

que transmite mejor su intención: los límites de un entero de 32 bits con signo.

Precompila tu expresión regular

Considere poner un

DIGIT_PATTERN = re.compile(r'^\s*[+-]?\d+')

en alcance global, para que múltiples llamadas a myAtoisean más rápidas.

Nunca desnudo except

Probablemente debería hacerlo en su lugar except ValueError, que es más estrecho y bien definido.