8. 字符串转换整数 (atoi) String to Integer

Implement atoi which converts a string to an integer.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned.

Note:

      

  • Only the space character ' ' is considered a whitespace character.
  • Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−2^31,  2^31 − 1]. If the numerical value is out of the range of representable values, 2^31 − 1 or −2^31 is returned.

 

方法一:

      自动机或有限状态机

    

我们的程序在每个时刻有一个状态 s,每次从序列中输入一个字符 c,并根据字符 c 转移到下一个状态 s'。这样,我们只需要建立一个覆盖所有情况的从 s 与 c 映射到 s' 的表格即可解决题目中的问题。

 

 

 

 

复制代码
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"});
        }};
        private  void get(char c){
            state = table.get(state)[get_col(c)];
            if ("in_number" == 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;
            }else if( c == '+' || c == '-'){
                return 1;
            }else if( Character.isDigit(c)){
                return 2;
            }else{
                return 3;
            }
        }
    }
复制代码

时间复杂度 O(n)

 

方法二:

       顺序遍历。

      先去掉空格,再去掉+-号,然后开始解析数字,注意溢出。

复制代码
public int myAtoi(String str) {
        int len = str.length();
        char[] charArray = str.toCharArray();

        int index = 0;
        while (index < len && charArray[index] == ' ') {
            index++;
        }

        if (index == len) {
            return 0;
        }

        int sign = 1;
        char firstChar = charArray[index];
        if (firstChar == '+') {
            index++;
        } else if (firstChar == '-') {
            index++;
            sign = -1;
        }

        int ans = 0;
        while (index < len) {
            char c = charArray[index];

            if (c > '9' || c < '0') {
                break;
            }

            if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && (c - '0') > Integer.MAX_VALUE % 10)) {
                return Integer.MAX_VALUE;
            }
            if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && (c - '0') > -(Integer.MIN_VALUE % 10))) {
                return Integer.MIN_VALUE;
            }
            ans = ans * 10 + sign * (c - '0');
            index++;
        }
        return ans;
    }
复制代码

 

 

方法三:

     正则表达式

     

复制代码
public int myAtoi(String str) {
        String pattern = "^\\s*([+-]?\\d+)";
        Pattern r = Pattern.compile(pattern);

        Matcher m = r.matcher(str);
        if (!m.find( ))  {
            return 0;
        }
        
        BigInteger ans = new BigInteger(m.group(1));
        if(ans.compareTo(new BigInteger(String.valueOf(Integer.MIN_VALUE)))<0){
            return Integer.MIN_VALUE;
        }
        if(ans.compareTo(new BigInteger(String.valueOf(Integer.MAX_VALUE)))>0){
            return Integer.MAX_VALUE;
        }
        return ans.intValue();
        
    }
复制代码

 

 

参考链接

https://leetcode.com/problems/string-to-integer-atoi/

https://leetcode-cn.com/problems/string-to-integer-atoi

posted @   diameter  阅读(106)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示