Oferta de Jianzhi (C++) -JZ67: Convertir cadena a entero atoi (simulación de algoritmo)

Autor: Zhai Tianbao Steven
Declaración de derechos de autor: Los derechos de autor pertenecen al autor. Para reimpresiones comerciales, comuníquese con el autor para obtener autorización. Para reimpresiones no comerciales, indique la fuente.

Tema Descripción:

Escriba una función StrToInt para convertir una cadena en un número entero. No puede utilizar atoi u otras funciones de biblioteca similares. La cadena entrante puede constar de las siguientes partes:

1. Varios espacios

2. (Opcional) Un carácter de signo ('+' o '-')

3. Expresión de cadena compuesta de números, letras, símbolos y espacios.

4. Algunos espacios

El algoritmo de conversión es el siguiente:
1. Elimina los espacios iniciales inútiles
2. Cuando el primer carácter no vacío es un signo + o -, se utiliza como signo del número entero. Si no hay signo, el valor predeterminado es positivo número
3. Determine la parte válida del número entero:
3.1 Después de determinar el bit de signo, combínelo con tantos números consecutivos como sea posible para convertirse en un número entero válido. Si no hay una parte entera válida, devuelva directamente 0. 3.2
Sacar la parte entera delante de la cadena, puede haber otras redundantes más adelante Caracteres (letras, símbolos, espacios, etc.), estos caracteres se pueden ignorar, no deberían tener impacto en la función 3.3 El número entero excede el
32- rango de enteros con signo de bits [−2 31 , 2 31  − 1], el número entero debe truncarse para que permanezca dentro de este rango. Específicamente, los números enteros menores que −2 31 deben ajustarse a −2 31  y los números enteros mayores que 2 31  − 1 deben ajustarse a 2 31  − 1
4. Elimine los espacios finales inútiles

rango de datos:

1,0 <= longitud de la cadena <= 100

2. La cadena consta de letras inglesas (mayúsculas y minúsculas), números (0-9), ' ', '+', '-' y '.'

Ejemplo:

ingresar:

"4396 amor claro"

valor de retorno:

4396

ilustrar:

Los caracteres después del 6 no pertenecen a la parte entera válida y se eliminan, pero se devuelve la parte válida extraída anteriormente.

Ideas para resolver problemas:

Esta pregunta examina la simulación de escenarios algorítmicos. Dos formas de resolver el problema.

1) método transversal

       Primero, filtre los espacios iniciales; luego juzgue los signos positivos y negativos; luego juzgue los números consecutivos, prestando atención al juicio de límite positivo y negativo durante el proceso; cada vez que encuentre un nuevo número, agregue el número anterior * 10, y puede obtener la respuesta después de atravesar. Complejidad O(n).

2) máquina de estados

       Analice el estado del proceso de recorrido de cadenas en función de la matriz de transición de estado.

       El estado se divide en 4 tipos, espacios, símbolos, números e inválido, correspondientes a 0123. La matriz se configura según las condiciones de la pregunta de la siguiente manera:

\begin{bmatrix} 0 y 1 y 2 y 3\\ 3 y 3 y 2 y 3\\ 3 y 3 y 2 y 3 \end{bmatrix}

  1. El estado inicial es 0 y se analiza la primera línea: si se encuentra un espacio, el siguiente estado sigue siendo 0; si se encuentra un símbolo, el estado cambia a 1; si se encuentra un número, el estado cambia a 2; si se encuentra un carácter no válido, el estado cambia a 3.
  2. Supongamos que el estado cambia a 1, analice la segunda línea: si se encuentra un espacio, es decir, + espacio, no es válido, por lo que la primera columna de la segunda línea es 3; si se vuelve a encontrar un símbolo, como + -, tampoco es válido, por lo que la segunda línea La segunda columna es 3; si se encuentra un número, como -3, el estado cambia a 2; si se encuentra un carácter no válido, el estado cambia a 3.
  3. Supongamos que el estado cambia a 2, analice la tercera línea: si se encuentra un espacio, como +8 espacio u 8 espacio, los pasos posteriores no serán válidos, por lo que la primera columna de la tercera línea es 3; si un símbolo es encontrado, como +8+ u 8+, los siguientes también no son válidos, por lo que la segunda columna de la tercera línea es 3; si se encuentra un número, como +89 u 89, los siguientes son válidos, por lo que el la tercera columna de la tercera línea es 2; los caracteres no válidos no son válidos de la misma manera.
  4. Cuando el estado es 2, los números se acumulan y se realiza un juicio fuera de los límites; cuando el estado es 3, simplemente interrumpa para salir.

       En general, la máquina de estados representa las posibles situaciones y transiciones de estado en forma matricial según los requisitos de la pregunta y luego resuelve el problema. Complejidad O(n).

Código de prueba:

1) método de clasificación

#include <climits>
class Solution {
public:
    // 字符串转为整数
    int StrToInt(string s) {
        int sign = 1;
        int idx = 0;
        int size = int(s.size());
        // 前空格过滤,过滤完如果没有后续则退出
        while(idx < size){
            if(s[idx] == ' ')
                idx++;
            else
                break;
        }
        if(idx == size)
            return 0;
        // 判断符号,如果没有后续则退出
        if(s[idx] == '+')
            idx++;
        else if(s[idx] == '-'){
            idx++;
            sign = -1;
        }
        if(idx == size)
            return 0;
        // 继续遍历寻找目标数字
        int result = 0;
        while(idx < size){
            // 遇到非数字退出
            if(s[idx] < '0' || s[idx] > '9')
                break;
            // 判断极限
            if(result > INT_MAX / 10 || (result == INT_MAX / 10 && (s[idx] - '0') >= (INT_MAX % 10)))
                return INT_MAX;
            if(result < INT_MIN / 10 || (result == INT_MIN / 10 && (s[idx] - '0') >= -(INT_MIN % 10)))
                return INT_MIN;
            // 字符转为数字
            result = result * 10 + sign * (s[idx] - '0');
            idx++;
        }
        return result;
    }
};

2) máquina de estados

class Solution {
public:
    // 字符串转为整数
    int StrToInt(string s) {
        // 状态转移矩阵
        vector<vector<int>> states = {
            {0,1,2,3},
            {3,3,2,3},
            {3,3,2,3},
        }; 
        // 定义
        long result = 0;
        long top = INT_MAX;  
        long bottom = INT_MIN;
        int sign = 1;
        int size = int(s.length());
        // 状态从0开始
        int state = 0; 
        for(int i = 0; i < size; ++i){
            // 空格
            if(s[i] == ' '){
                state = states[state][0]; 
            }
            // 正负号 
            else if(s[i] == '-' || s[i] == '+'){ 
                state = states[state][1]; 
                if(state == 1){
                    sign = (s[i] == '-') ? -1 : 1;
                }    
            }
            // 数字
            else if(s[i] >= '0' && s[i] <= '9'){
                state = states[state][2]; 
            }   
            // 非法字符
            else{
                state = states[state][3]; 
            }
            // 状态为2时,表明在连续数字状态,进行数字累加
            if(state == 2){
                // 数字相加
                result = result * 10 + s[i] - '0'; 
                // 越界处理
                result = (sign == 1) ? min(result, top) : min(result, -bottom); 
            }
            // 状态为3时,说明后续无效,退出即可
            else if(state == 3)
                break;
        }
        return (int)sign * result;
    }
};

Supongo que te gusta

Origin blog.csdn.net/zhaitianbao/article/details/132844648
Recomendado
Clasificación