LeetCode Brushing Notes 08 Cadena a entero

Autor: Ma Zhifeng
Enlace: https: //zhuanlan.zhihu.com/p/24047577
Fuente: saber casi con
derechos de autor del autor. Para reimpresiones comerciales, comuníquese con el autor para obtener autorización. Para reimpresiones no comerciales, indique la fuente.

enlace

leetcode.com/problems/s

tema

Darse cuenta de atoi, convertir cadena en entero

Paráfrasis

El enfoque de esta pregunta es considerar qué posibles situaciones

  1. Cómo lidiar con caracteres que no son dígitos
  2. Firmar
  3. Desbordamiento

Por supuesto, la idea es definitivamente procesar cada carácter de la cadena, entonces, ¿cómo convertir el carácter '1' en el número 1?

El hermano Xiao Ma es bastante estúpido, no lo esperaba.

Pensé que podría estar relacionado con la tabla ASCII, pero no pude estudiarlo en profundidad y finalmente eché un vistazo a la respuesta. . .

Eres bendecido, si no lo esperas, ya no necesitas leer la respuesta, te lo diré

'1' - '0' = 1;

Sí, solo resta del carácter 0. Porque son continuos en la tabla

De acuerdo, el problema clave está resuelto, veamos cómo lidiar con algunos casos especiales

  1. Para los caracteres que no son dígitos, podemos ignorar los caracteres vacíos al principio y al final ("23"). Si hay otros caracteres ("123x21") en el medio del número, se considerará una entrada ilegal.
  2. Firmar, necesita ser guardado
  3. Desbordamiento, todavía tenemos el método del tema anterior, usamos long long para tratar

Descripción complementaria

Podemos escribir algunos casos de prueba basados ​​en la descripción complementaria del tema:

  1. “123” → 123
  2. "-123" → -123
  3. "123 x 456" → 123
  4. “123 456” → 123
  5. “343485894858938553” → INT_MAX
  6. “” → 0
  7. "Xxxyyy" → 0

Antes de hacer las preguntas, puede obtener una vista previa de las operaciones de caracteres que admite C ++, consulte "Introducción a C ++" Quinta edición (edición china) P82, Tabla 3.3

Todo está listo, empieza a hacer el problema formalmente

Código

class Solution {
      
        
public:  
    int myAtoi(string str) {
      
        

        int iFlag = 1;  

        bool bStart = false;  
        vector<int> vecDigits;  

        for( auto c : str )  
        {
      
        
            if( !bStart )  
            {
      
        
               if( isspace(c) )  
                {
      
        
                    continue;  
                }   

                if( ('+' == c || '-' == c ) )  
                {
      
        
                    iFlag = '+' == c ? 1 : -1;  
                    bStart = true;  
                    continue;  
                }  
            }  

            if( isdigit(c) )  
            {
      
        
                bStart = true;  
                vecDigits.push_back( c - '0' );  
            }  
            else  
            {
      
        
                break;  
            }  
        }  

        if( vecDigits.size() == 0 )  
        {
      
        
            return 0;  
        }  

        long long result = 0;  
        long long iFactor = 1;  

        auto i = vecDigits.size();  
        while( i > 0 )  
        {
      
        
            --i;  
            result += iFactor * vecDigits[i];  
            iFactor *= 10;  

            if( result*iFlag > INT_MAX )  
            {
      
        
                return INT_MAX;  
            }  

            if( result*iFlag < INT_MIN )  
            {
      
        
                return INT_MIN;  
            }  
        }  

        return result*iFlag;  
    }  
};

La lógica es un poco complicada, déjame explicarte:

  1. El primer bucle for se utiliza para insertar números legales en un vector.
    • iFlag se usa para guardar la señal
    • bStart se usa para guardar si el número ya ha sido procesado. La razón para agregar esta bandera es porque el espacio antes del número y el espacio después del número se manejan de manera diferente
  2. Si después del ciclo for, el vector todavía está vacío, no hay un número legal y se devuelve 0 directamente
  3. La siguiente instrucción while se usa para obtener un número entero, de la misma manera que la pregunta anterior. El juicio de desbordamiento se coloca dentro del bucle para evitar una cuerda más larga que larga.

Por supuesto, este código también se ha modificado varias veces para transmitir el LeetCode.

Entonces veamos si podemos simplificar la lógica anterior

Antes de modificar el código, tenemos que pensar en una pregunta, ¿cómo garantizar la corrección de la lógica al simplificar el código?

Este es un problema muy común y con frecuencia lo encontraremos durante el proceso de codificación. Al principio, quería ser responsable del código y luchar por la perfección. Como resultado, la velocidad aumentó, pero el resultado no fue el correcto. No vale la pena ganarlo.

Para resolver este problema, puede probar el método de "desarrollo basado en pruebas", es decir, diseñar casos de prueba antes de comenzar a escribir código. Si el código puede pasar todos los casos de prueba, cumple con nuestros requisitos funcionales. Al realizar modificaciones de código posteriores, debe asegurarse de que todos los casos de uso pasen. Si los casos de uso fallan, significa que hay un problema con el código modificado.

Al igual que los casos de uso que escribimos anteriormente, por supuesto, estos casos de uso definitivamente no son suficientes, pero son mucho mejores que no escribir nada. ¡Ya sabes, hay 1047 casos de prueba para este tema en leetcode!

Al escribir algunos programas pequeños, podemos usar assert para completar el juicio de resultado.

//leetcode08.h  

#include <string  

using std::string;  

class Solution08 {  
public:  
    static int myAtoi(string str);  
};
//main  

#include "cassert"  

assert(Solution::myAtoi("123")== 123);  
assert(Solution08::myAtoi("123") == 123);  
assert(Solution08::myAtoi("-123") == -123);  
assert(Solution08::myAtoi("    -123   ") == -123);  
assert(Solution08::myAtoi("    123   456   ") == 123);

Complete los casos de prueba anteriores y luego piense si hay otros escenarios. Si hay alguno, no sea tacaño con el uso de casos de prueba, cuanto más, mejor.

Supongo que te gusta

Origin blog.csdn.net/qq_26751117/article/details/53442419
Recomendado
Clasificación