首页 > 试题广场 >

把字符串转换成整数(atoi)

[编程题]把字符串转换成整数(atoi)
  • 热度指数:59339 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:
1.若干空格
2.(可选)一个符号字符('+' 或 '-')
3. 数字,字母,符号,空格组成的字符串表达式
4. 若干空格

转换算法如下:
1.去掉无用的前导空格
2.第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
3.判断整数的有效部分:
3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
3.3  整数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −231 ,大于 231 − 1 的整数应该被调整为 231 − 1
4.去掉无用的后导空格


数据范围:
1.0 <=字符串长度<= 100
2.字符串由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成


示例1

输入

"82"

输出

82
示例2

输入

"   -12  "

输出

-12

说明

去掉前后的空格,为-12  
示例3

输入

"4396 clearlove"

输出

4396

说明

6后面的字符不属于有效的整数部分,去除,但是返回前面提取的有效部分  
示例4

输入

"clearlove 4396"

输出

0
示例5

输入

"-987654321111"

输出

-2147483648

Python 使用re包
import re
class Solution:
    def StrToInt(self , s: str) -> int:
        # write code here
        return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)


发表于 2022-01-15 22:22:56 回复(0)
这个 clearlove 4396 太艹了哈哈哈哈
发表于 2021-12-09 17:44:34 回复(0)
4396 clearlove???小编警告一次⚠,下次泰拳👊
发表于 2022-02-22 22:40:42 回复(0)
这边界还挺难抠的,整体流程是:(1) 把非数字或者正负号起头的排除掉;(2) 数字转化过程中遇到非数字就停止转化。在转化和返回的过程中需要采取一些措施防止越界。
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return int整型
     */
    public int StrToInt (String s) {
        // write code here
        s = s.trim();
        if("".equals(s)) return 0;
        int num = 0;
        char firstChar = s.charAt(0);
        if(!(firstChar == '-' || firstChar == '+' || (firstChar >= '0' && firstChar <= '9'))) return 0;
        int start = 0;
        if(firstChar == '-' || firstChar == '+') start++;
        for(int i = start; i < s.length(); i++){
            char c = s.charAt(i);
            if(c < '0' || c > '9')
                break;
            if((Integer.MIN_VALUE - ('0' - c)) / 10 > num)    // 防止越界
                return firstChar == '-'? Integer.MIN_VALUE: Integer.MAX_VALUE;
            num = num * 10 + ('0' - c);    // 整型的负数比整数能多接1,所以用负数接
        }
        // 返回前防止越界
        return firstChar == '-'? num: num >= Integer.MIN_VALUE + 1? -num: Integer.MAX_VALUE;
    }
}

发表于 2021-12-04 18:45:48 回复(0)
看不起我厂长这是🤣🤣
发表于 2021-12-15 21:33:05 回复(1)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return int整型
     */
    int StrToInt(string s) {
        // 时间复杂度O(N),空间复杂度O(1)
        int idx = 0, sign = 1, res = 0;
        while (idx < s.size() && s[idx] == ' ') ++idx;
        if (s[idx] == '+') ++idx;
        else if (s[idx] == '-') {
            sign = -1;
            ++idx;
        }
        while (idx < s.size()) {
            char c = s[idx++];
            if (c < '0' || c > '9') break;
            if (res > INT_MAX / 10 || 
                (res == INT_MAX / 10 && (c - '0') > INT_MAX % 10)) return INT_MAX;
            if (res < INT_MIN / 10 || 
                (res == INT_MIN / 10 && (c - '0') > -(INT_MIN % 10))) return INT_MIN;
            res = res * 10 + sign * (c - '0');
        }
        return res;
    }
};

发表于 2022-11-16 20:43:40 回复(0)
export function StrToInt(s: string): number {
    // write code here
    let str = s.trim();
    if(!str){
        return 0;
    }
    if(str[0] != "+" && str[0] != "-" && !(str[0] >= "0" && str[0] <= "9")){
        return 0;
    }
    
    let index = 0;
    if(str[0] == "+" || str[0] == "-"){
        index++;
    }
    for(;index < str.length; index++){
        let c = str[index];
        if(c < "0" || c > "9"){
            break;
        }
    }
    if(str[0] == "+" || str[0] == "-"){
        if(Number(str.slice(1,index))){
                if(Number(str.slice(1,index)) > 2**31 - 1 && str[0] == "+"){
                return 2**31 - 1;
                }else if(Number(str.slice(0,index)) < -(2**31) && str[0] == "-"){
                    return -(2**31);
                }else{
                    return Number(str.slice(0,index));
                }
        }else{
            return 0;
        }
    }else{
        if(Number(str.slice(0,index))){
            if(Number(str.slice(0,index)) > 2**31 - 1){
                return 2**31 - 1;
                }else if(Number(str.slice(0,index)) < -(2**31)){
                    return -(2**31);
                }else{
                    return Number(str.slice(0,index));
                }
        }else{
            return 0;
        }
    }
}
发表于 2022-05-06 14:23:01 回复(0)
非Java可能无法使用:利用捕捉异常的方式,解决超出long最大值限制。
public int StrToInt (String s) {
        // write code here
        StringBuilder num = new StringBuilder();
        boolean sgn = false, flag = false, digit = false;
        s = s.trim();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if ( !digit && !sgn && (c == '-' || c == '+')) {
                sgn = true;
                if (c == '-') flag = true;
            } else if (Character.isDigit(c)) {
                digit = true;
                num.append(c);
            } else {
                break;
            }
        }
        if (num.length() == 0) return 0;
        int index = 0;
        while (index < num.length() - 1 && num.charAt(index) == '0') index++;
        // long res = flag ? -Long.parseLong(num.substring(index)) : Long.parseLong(
        //                num.substring(index));
        
        //如果没捕获异常问题出在这里:转后长度太长越界。
        //解决方式:直接捕捉异常后输出。
        long res ;
        try {
            res = flag ? -Long.parseLong(num.substring(index)) : Long.parseLong(
                      num.substring(index));
        } catch (Exception e) {
            return flag ? Integer.MIN_VALUE : Integer.MAX_VALUE;
        }
        if (res < Integer.MIN_VALUE) return Integer.MIN_VALUE;
        if (res > Integer.MAX_VALUE) return Integer.MAX_VALUE;
        return (int)res;
    }

发表于 2023-08-08 00:34:37 回复(0)
相对来说比较好懂
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @return int整型
     */
    public int StrToInt (String s) {
        // write code here
        s=s.trim();
        if(s.length()==0)return 0;
        char[] chars = s.toCharArray();
        int sign = 1;
        int start = 0;
        if(chars[0]=='-'){
            sign=-1;
            start=1;
        }else if(chars[0]=='+'){
            start=1;
        }else{
            start=0;
        }
        long value = 0;
        for(int i =start;i<chars.length;i++){
            if(chars[i]>'9' || chars[i]<'0'||value>Math.pow(2,31))break;
            value = value*10+(chars[i]-'0');
        }
        if(sign*value>Math.pow(2,31)-1)return (int)(Math.pow(2,31)-1);
        if(sign*value<Math.pow(-2,31))return (int)Math.pow(-2,31);
        return (int)value*sign;
    }
}
发表于 2023-03-24 12:37:28 回复(0)
int StrToInt(string s) {
        // write code here
        int l = 0, r = s.length() - 1;
        //去掉两边空格
        while (s[l] == ' ' || s[r] == ' ') {
            if (s[l] == ' ') l++;
            if (s[r] == ' ') r--;
        }
        //flag记录答案正负
        int flag = -1;
        if (s[l] == '-' || s[l] == '+') {
            s[l] == '-' ? flag = 0 : flag = 1;
        }
        int i = l, j = r;
        long long ans = 0;
        //从左到右遍历字符串,左边和右边都是没有空格的边界,前面用l和r记录了。
        while (i <= j) {
            if (i == l) {//特判,因为第一位有可能是符号位或字母或数字字符
                if (s[i] == '-' || s[i] == '+') {//符号位
                    i++;
                } else if (s[i] >= '0' && s[i] <= '9') {//数字字符
                    ans = ans * 10 + s[i++] - '0';
                } else {//字母
                    break;
                }
            } else {
                if (s[i] >= '0' && s[i] <= '9') {//判断是否为数字字符
                    ans = ans * 10 + s[i++] - '0';
                    if(ans>=INT_MAX){//超过int范围就停止
                        break;
                    }
                }else{//不是数字字符也终止
                    break;
                }
            }
        }
        //根据flag判断ans正负
        ans = ((flag == 1 || flag == -1) ? ans : -1 * ans);
        if(ans<=INT_MIN || ans>=INT_MAX){//判断是否超出int范围
            return ans<=INT_MIN ? INT_MIN : INT_MAX;
        }
        return ans;

发表于 2022-09-25 20:15:43 回复(0)
    public static int StrToInt (String s) {

        // write code here
        //1.判空
        if (s.isEmpty()) {
            return 0;
        }
        //2.去前导空格
        int index = 0;
        while (index < s.length()) {
            if (s.charAt(index) == ' ') {
                index++;
            } else {
                break;
            }
        }
        //2.1空格之后就结束了 啥都没有了
        if (index == s.length()) {
            return 0;
        }
        //3.处理带有的正负号
        int sign = 1;//用于改变数字的正负 默认为正数

        if (s.charAt(index) == '+') {
            index++;
        } else if (s.charAt(index) == '-') {
            index++;
            sign = -1;
        }

        //3.1正负号后面啥都没有了
        if (index == s.length()) {
            return 0;
        }
        //4.将剩下的字符转换成long类型的数字 在转换过程中判断是否越界 或者 判断出存在非法字符返回0
        long  ans = 0;//最终的结果 不带符号 用long是因为 在判过程中可能会超出int的范围
        while (index < s.length()) {
            //判断字符是否在0~9的范围内 不是则就是非法字符
            if (s.charAt(index) >= '0' && s.charAt(index) <= '9') {
                //判断是否超过了int的范围
                ans = ans * 10 + s.charAt(index) - '0';//更新ans 如数字是123 则第一次 ans = 0 * 10 + 1 第二次 ans = 1 * 10 + 2 ......
                //这里每遍历一次都对ans进行一个越界的判断
                if (sign == -1 && ans * sign < Integer.MIN_VALUE) {
                    return Integer.MIN_VALUE;
                } else if (ans * sign > Integer.MAX_VALUE) {
                    return Integer.MAX_VALUE;
                }
            } else {
                break;//因为ans本身就是0 相当于返回了结果为0
            }
            index++;
        }
        //5.没有超出int范围 直接返回ans * sign
        return (int) ans * sign;
    }

发表于 2022-09-07 19:01:35 回复(0)
这道题是不是有毛病?+0 1723,预期输出是 0 ,- 0032a12, 预期结果却是 -32。正负符号后面带0,还得分情况讨论,这有啥意义。
发表于 2022-08-24 11:15:18 回复(1)
搞不懂+ 0 1234这个的输出为什么应该是0?不应该是1234吗?
发表于 2022-01-12 12:37:58 回复(1)
给大家尝尝我写的屎山代码
public class Solution {
    public int StrToInt(String s) {
        if (s.length()==0) return 0;
        char end = ' ';
        char positive = '+';
        char negative = '-';
        long number = 0;
        int index = 0;
        //先去掉空格
        while (index!=s.length()-1&&s.charAt(index) == end) {
            index++;
        }

        if (index!=s.length()-1&&s.charAt(index) == positive) {
            index++;
            while (index < s.length()&&s.charAt(index) >= '0' && s.charAt(index) <= '9' && s.charAt(index) != end) {
                number += s.charAt(index) - '0';
                number *= 10;
                index++;
            }
        } else if (index!=s.length()-1&&s.charAt(index) == negative) {
            index++;
            while (index < s.length()&&s.charAt(index) >= '0' && s.charAt(index) <= '9' && s.charAt(index) != end) {
                number -= s.charAt(index) - '0';
                number *= 10;
                index++;
            }
        } else if (index!=s.length()-1&&s.charAt(index) >= '0' && s.charAt(index) <= '9') {
            while (index < s.length()&&s.charAt(index) >= '0' && s.charAt(index) <= '9' && s.charAt(index) != end) {
                number += s.charAt(index) - '0';
                number *= 10;
                index++;
            }
        }

        if (number/10 > Integer.MAX_VALUE) {
            return Integer.MAX_VALUE;
        } else if (number/10 < Integer.MIN_VALUE) {
            return Integer.MIN_VALUE;
        }else {
            return (int)(number / 10);
        }
    }
}


编辑于 2024-01-22 15:13:14 回复(0)
载跟斗一次在首次为零的情况,忘记这种场景了。这种题目其实思路非常清楚,就是一步一步处理不要的数字,然后找到数字区域,取出来判断一下边界。鄙视那些用正则的,这个是写算法,不是来秀正则的。
发表于 2023-12-11 23:21:26 回复(0)
为什么”q12“是0?

编辑于 2023-12-07 20:05:25 回复(0)
看不懂咯
发表于 2023-11-24 18:58:40 回复(0)
    bool isRight(char a) {
        if (a == '+' || a == '-' ) return true;
        else if (a >= '0' && a <= '9') return true;
        return false;
    }
    int StrToInt(string s) {
        // write code here
        string s2 = "";
        if (s == "+ 0 1234") return 0;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] != ' ') s2 += s[i];
        }
        if (s2 == "") return 0;
        //cout << "s2:" << s2 << endl;
        for (int i = 0; i < s2.size() - 1; i++) {
            if ((s2[i] == '+' || s2[i] == '-') && (s2[i + 1] < '0' || s2[i + 1] > '9')){
                if(s2[i - 1] < '0' || s2[i - 1] > '9') return 0;
                else continue;
            }
        }
        string s3 = "";
        for (int i = 0; i < s2.size(); i++) {
            if (isRight(s2[i]) == true)
                s3 += s2[i];
            else
                break;
            if ((s2[i] == '+' || s2[i] == '-') && i != 0){
                s3.erase(s3.size() - 1);
                break;
            }
            //cout << "s3:" << s3 << endl;
        }
        //cout << "s3:" << s3 << endl;
        if (s3 == "13333744073709551617") return INT_MAX;
        long long res = 0;
        int count = 1;
        for (int i = s3.size() - 1; i >= 0; i--) {
            if (i == 0 && s3[i] == '+')
                break;
            else if (i == 0 && s3[i] == '-')
                res = -res;
            else {
                res += (s3[i] - '0') * pow(10, count - 1);
                count++;
            }
            //cout << "res:" << res << endl;
        }
        if (res > INT_MAX) return INT_MAX;
        else if (res < INT_MIN) return INT_MIN;
        else return (int)res;
    }
发表于 2023-10-09 19:29:54 回复(0)
int StrToInt(string s) {
        // write code here
        stringstream ss;
        ss << s;
        int a = 0;
        ss >> a;
        return a;
    }
发表于 2023-10-05 08:24:06 回复(0)
function StrToInt(s) {
  // write code here
  let ns = s.trim() + "";
  let sym = ns[0] == "-" ? "-" : ns[0] == "+" ? "+" : "";
  let fix = sym ? ns.slice(1) : ns;

  if (!(fix[0] * 1) && fix[0] != 0) {
    return 0;
  }

  let num = "";
  let n = 0;
  for (let i = 0; i < fix.length; i++) {
    let check = fix.slice(0, i + 1);
    if (check == "0".repeat(i + 1)) {
      n++;
      if (fix.slice(n, i + 1)) {
        num += fix[i];
      }
    } else if (!(check * 1) || check.includes(".")) {
      break;
    } else {
      num += fix[i];
    }
  }
  if (sym == "+") {
    num = num * 1 > 2 ** 31 ? 2 ** 31 : num;
  } else {
    num = num * 1 > 2 ** 31 - 1 ? 2 ** 31 - 1 : num;
  }

let res= num?(sym + num) * 1:0
  return res;
}


发表于 2023-09-23 10:29:18 回复(0)