首页 > 其他分享 >力扣第八题——字符串转换整数

力扣第八题——字符串转换整数

时间:2024-07-15 23:26:46浏览次数:19  
标签:字符 end 状态 第八 整数 力扣 读入 ans 字符串

题目介绍

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

函数 myAtoi(string s) 的算法如下:

  1. 空格:读入字符串并丢弃无用的前导空格(" "
  2. 符号:检查下一个字符(假设还未到字符末尾)为 '-' 还是 '+'。如果两者都不存在,则假定结果为正。
  3. 转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
  4. 舍入:如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。

返回整数作为最终结果。

示例 1:

输入:s = "42"

输出:42

解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。

带下划线线的字符是所读的内容,插入符号是当前读入位置。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^

示例 2:

输入:s = " -042"

输出:-42

解释:

第 1 步:"   -042"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -042"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -042"(读入 "042",在结果中忽略前导零)
               ^

示例 3:

输入:s = "1337c0d3"

输出:1337

解释:

第 1 步:"1337c0d3"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"1337c0d3"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"1337c0d3"(读入 "1337";由于下一个字符不是一个数字,所以读入停止)
             ^

示例 4:

输入:s = "0-1"

输出:0

解释:

第 1 步:"0-1" (当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"0-1" (当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"0-1" (读入 "0";由于下一个字符不是一个数字,所以读入停止)
          ^

示例 5:

输入:s = "words and 987"

输出:0

解释:

读取在第一个非数字字符“w”处停止。

提示:

  • 0 <= s.length <= 200
  • s 由英文字母(大写和小写)、数字(0-9)、' ''+''-' 和 '.' 组成

完整代码

class Solution {
    public int myAtoi(String str) {
        Automaton automaton = new Automaton();
        int length = str.length();
        for (int i = 0; i < length; ++i) {
            automaton.get(str.charAt(i));
        }
        return (int) (automaton.sign * automaton.ans);
    }
}

class Automaton {
    public int sign = 1;
    public long ans = 0;
    private String state = "start";
    private Map<String, String[]> table = new HashMap<String, String[]>() {{
        put("start", new String[]{"start", "signed", "in_number", "end"});
        put("signed", new String[]{"end", "end", "in_number", "end"});
        put("in_number", new String[]{"end", "end", "in_number", "end"});
        put("end", new String[]{"end", "end", "end", "end"});
    }};

    public void get(char c) {
        state = table.get(state)[get_col(c)];
        if ("in_number".equals(state)) {
            ans = ans * 10 + c - '0';
            ans = sign == 1 ? Math.min(ans, (long) Integer.MAX_VALUE) : Math.min(ans, -(long) Integer.MIN_VALUE);
        } else if ("signed".equals(state)) {
            sign = c == '+' ? 1 : -1;
        }
    }

    private int get_col(char c) {
        if (c == ' ') {
            return 0;
        }
        if (c == '+' || c == '-') {
            return 1;
        }
        if (Character.isDigit(c)) {
            return 2;
        }
        return 3;
    }
}

 思路解析

1. 类 Solution

方法 myAtoi
  • 功能:将字符串转换为整数。
  • 参数str,表示输入的字符串。
  • 返回值:转换后的整数。

该方法首先创建一个 Automaton 对象,然后遍历字符串中的每个字符,调用 Automaton 对象的 get 方法进行处理。最后返回经过处理的整数结果。

2. 类 Automaton

成员变量
  • sign:表示正负号,默认为 1(正数)。
  • ans:存储转换后的整数结果。
  • state:表示当前状态,初始为 “start”。
  • table:状态转移表,用于根据当前状态和字符类型确定下一个状态。
方法 get
  • 功能:根据当前字符和状态,更新状态并处理整数转换。
  • 参数c,表示当前处理的字符。

该方法首先根据当前状态和字符类型,从状态转移表中获取下一个状态。然后根据下一个状态执行相应的操作:

  • 如果状态为 “in_number”,则将当前字符转换为整数并累加到 ans 中。同时,检查 ans 是否超出整数范围,并进行截断处理。
  • 如果状态为 “signed”,则根据字符是 ‘+’ 还是 ‘-’ 设置 sign 的值。
方法 get_col
  • 功能:根据字符类型返回对应的列索引。
  • 参数c,表示当前处理的字符。
  • 返回值:列索引,用于在状态转移表中查找下一个状态。

该方法根据字符类型返回对应的列索引:

  • 空格:返回 0
  • 正负号:返回 1
  • 数字:返回 2
  • 其他字符:返回 3

代码执行流程

  1. 创建 Automaton 对象,初始化状态为 “start”。
  2. 遍历输入字符串中的每个字符。
  3. 调用 Automaton 对象的 get 方法,根据当前字符和状态进行状态转移。
  4. 在状态转移过程中,如果遇到数字,则累加到 ans 中,并处理整数范围溢出。
  5. 如果遇到正负号,则设置 sign 的值。
  6. 遍历结束后,根据 sign 和 ans 计算最终结果并返回。

知识点精炼

  1. 字符串处理:掌握字符串的基本操作,如遍历和字符类型判断。
  2. 有限状态机:理解状态机的概念,能够根据不同输入进行状态转移。
  3. 符号识别:能够处理正负号,并影响最终结果的符号。
  4. 整数累加与范围控制:在累加过程中注意整数类型的范围限制,防止溢出。
  5. 映射表应用:利用哈希表实现状态转移逻辑,提高代码的可读性和效率

标签:字符,end,状态,第八,整数,力扣,读入,ans,字符串
From: https://blog.csdn.net/m0_74932528/article/details/140451409

相关文章

  • 第六章字符串及正则表达式
    字符串的常用操作点击查看代码示例6-1字符串的相关操作1#大小写转换s1='HELLOWORLD'new_s2=s1.lower()print(s1,new_s2)new_s3=s1.upper()print(new_s3)#字符串的分隔e_mail='[email protected]'lst=e_mail.split('@')print('邮箱名:',lst[0],'邮箱服务器:',......
  • 字符串专题
    哈希好用的哈希模数:unsignedlonglong/longlong自然溢出\(2654435769\)(存疑)\(1610612741\)(极力推荐)\(998244353\),\(10^9+7\)(经典,貌似容易被×)提供一种\(N\)模数哈希的写法:LuoguP3546#include<bits/stdc++.h>#defineintlonglong#definelllonglong#define......
  • 【力扣 709】转换成小写字母 C++题解(字符串)
    给你一个字符串s,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。示例1:输入:s=“Hello”输出:“hello”示例2:输入:s=“here”输出:“here”示例3:输入:s=“LOVELY”输出:“lovely”提示:1<=s.length<=100s由ASCII字符集中的可打印字符组......
  • 【力扣 58】最后一个单词的长度 C++题解(字符串)
    给你一个字符串s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。单词是指仅由字母组成、不包含任何空格字符的最大子字符串。示例1:输入:s=“HelloWorld”输出:5解释:最后一个单词是“World”,长度为5。示例2:输入:s="flymetot......
  • C++字符串String和字符串字面量String Literals
    在C++中,字符串(String)是一种用于表示和处理文本数据的基本类型。C++提供了两种主要的字符串类型:C风格字符串(C-StyleString):使用字符数组表示。标准库字符串(std::string):使用标准库中的std::string类表示。1.C风格字符串C风格字符串是一个以空字符(\0)结尾的字符数组。以下是......
  • 力扣-187. 重复的DNA序列
    1.题目题目地址(187.重复的DNA序列-力扣(LeetCode))https://leetcode.cn/problems/repeated-dna-sequences/题目描述DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G' 和 'T'.。例如,"ACGAATTCCG" 是一个DNA序列。在研究DNA时,识别DNA中的重复序列非常有用。......
  • 代码随想录算法训练营第10天|232. 用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047.
    学习任务:Leetcode232.用栈实现队列Leetcode225.用队列实现栈Leetcode20.有效的括号Leetcode1047.删除字符串中的所有相邻重复项Leetcode232.用栈实现队列难度:简单|相关标签:栈、设计、队列题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支......
  • 判断字符串相等
    “==”操作符用于比较两个对象的地址是否相等。.equals()方法用于比较两个对象的内容是否相等。Strings1=newString("hh");Strings2=newString("hh");//trueSystem.out.println(s1.equals(s2));//falseSystem.out.println(s1==s2);Object类的equals()/......
  • 字符串拼接
    StringBuilder的append()Strings1="ha";Strings2="xi";//编译的时候被替换成newStringBuilder(s1).append(s2).toString();System.out.println(s1+s2);Strings1="ha";//+号也被编译成了append()Strings2=s1+"";System.ou......
  • 字符串常量池
    newString()创建了几个对象//使用new,每次都会创建一个新的对象Strings=newString("hh");先在位于堆中的字符串常量池中查找是否已经存在hh字符串对象如果有,直接在堆中创建一个hh字符串对象,然后把这个堆中新创建的对象地址返回给栈中的变量s如果没有,现在字符串常量池......