题目的主要信息:

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成: 1.若干空格 2.(可选)一个符号字符('+' 或 '-')

  1. 数字,字母,符号,空格组成的字符串表达式
  2. 若干空格

方法一:

首先利用一个while循环去除空格,然后用flag保存符号位。用res保存已经转换的整数,遍历一遍字符串,将数字字符转换为整数,加到res的末尾。在遍历过程中需要注意边界情况,以下两种情况说明再添加数字将越界:

  • 当res为正整数时,如果res > INT_MAX/10 || res==INT_MAX/10 && s[index]-'0' > INT_MAX%10)表示正整数超过INT_MAX,要截断
  • 当res为负整数时,如果res < INT_MIN/10 || res==INT_MIN/10 && s[index]-'0' > -(INT_MIN%10)表示负整数小于INT_MAX,要截断 alt 具体做法:
class Solution {
public:
    int StrToInt(string s) {
        int index = 0;
        int res = 0, flag = 1;
        while(s[index] == ' ') index++;
        if(index < s.size() && (s[index] == '+' || s[index] == '-')) {
            if(s[index] == '-'){
                flag = -1;//判断符号位
            }
            index++;
            if(!isdigit(s[index])) return 0;//符号位后没有整数部分,返回0
        }
        while(index < s.size() && isdigit(s[index])) {
            if(flag==1){
                if(res > INT_MAX/10 || res==INT_MAX/10 && s[index]-'0' > INT_MAX%10) {//正整数超过INT_MAX要截断
                    return INT_MAX;
                }
            } else{
                    int temp = res*flag;
                    if(temp < INT_MIN/10 || temp==INT_MIN/10 && s[index]-'0' > -(INT_MIN%10)) {//负整数小于INT_MIN要截断
                        cout<<temp<<endl;
                        return INT_MIN;
                    }
            }
            res = res*10+s[index]-'0';//接上当前的数字
            index++;
        }
        return res*flag;
    }
};

复杂度分析:

  • 时间复杂度:O(n)O(n),需要遍历一遍字符串。
  • 空间复杂度:O(1)O(1),只用了常数空间。

方法二:

整体思路和方法一相同。方法二将res的类型改为long,可以储存64位整数。遍历一遍字符串,将当前数字字符拼在res之后,如果res超过了INT_MAX或INT_MIN,说明已经越界了,截断输出;否则继续遍历字符串。

具体做法:

class Solution {
public:
    int StrToInt(string s) {
        int index = 0;
        long res = 0;
        int flag = 1;
        while(s[index] == ' ') index++;
        if(index < s.size() && (s[index] == '+' || s[index] == '-')) {
            if(s[index] == '-'){
                flag = -1;//判断符号位
            }
            index++;
            if(!isdigit(s[index])) return 0;//符号位后没有整数部分,返回0
        }
        while(index < s.size() && isdigit(s[index])) {
            res = res*10+s[index]-'0';//接上当前的数字
            index++;
            if(flag==1){
                if(res > INT_MAX) {//正整数超过INT_MAX要截断
                    return INT_MAX;
                }
            } else{
                    long temp = res*flag;
                    if(temp < INT_MIN) {//负整数小于INT_MIN要截断
                        return INT_MIN;
                    }
            }
        }
        return res*flag;
    }
};

复杂度分析:

  • 时间复杂度:O(n)O(n),需要遍历一遍字符串。
  • 空间复杂度:O(1)O(1),只用了常数空间。