NO49、字符串转化为整数(挺好的题,需要考虑的情况很多,可以再刷一次)

本文提供几种将字符串转换为整数的有效算法实现,探讨如何处理符号、空格及非法字符等问题,确保转换过程准确无误。
49、字符串转化为整数 可以再刷一次

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0

输入描述:

输入一个字符串,包括数字字母符号,可以为空

输出描述:

如果是合法的数值表达则返回该数字,否则返回0

示例1

输入

+2147483647
1a33

输出

2147483647
0
1、自己思考的一种笨方法,这题用C++ AC 不了

负数 -1234,正数 +2563的情形 第一个为正负号 要考虑到

第一位为0的也是不是合法的

出现0~9之外的字符也是不合法的

    int StrToInt(string str) {
	long long num = 0;
	if (str.size() == 0) return 0;
	int len = str.size();
	bool isNegative = false,isPositive = false;
	if (str[0] == '-') isNegative=true;
	else if (str[0] == '+') isPositive = true;
	else
		if (str[0]<='0' || str[0]>'9')  return 0;

	int i = 0;
	if (isPositive || isNegative) i = 1;
	for (    ; i <len ; ++i) {
		if (str[i]<'0' || str[i]>'9') return 0;
		else {
			num = num * 10 + str[i] - '0';
		}

	}
	if (isNegative) num = -1 * num;
	if (num <= INT_MAX && num >= INT_MIN) return num;
    return 0;
    }

只通过85.71%的案例。

2、第二种精简一点的方法
    int StrToInt(string str) {
    int len = str.size();
	if (len == 0) return 0;//为空,直接返回即可
	int i = 0, flag = 1,isSingal = 0;// 索引 正负号标志位  正负号出现次数
	long res = 0; //默认flag = 1,正数
	while (i<len && str[i] == ' ') i++; //若str全为空格,str[i] = '\0'(最后一个i)
	if (i >= len) return 0;//全部都是空格,直接返回吧
	if (i < len && str[i] == '-') { flag = -1; ++i; isSingal++; }
	if (i < len && str[i] == '+') { ++i; ++isSingal; }
	if (isSingal > 1) return 0;
	for (  ; i < len ; ++i) {
		if(str[i]<'0' || str[i] > '9') return 0;
        res = res * 10 + (str[i] - '0');
		if (res >= INT_MAX && flag == 1) return  INT_MAX;
		if (res > INT_MAX && flag == -1) return  INT_MIN;
	}
	return flag * res;
        
    }
3、有很多要注意的地方
int StrToInt(string str) {
	
	int len = str.size();
	if (len == 0) return 0;
	int  flag=1,singal=0, i = 0;
	long long num = 0;
	while (i < len && str[i] == ' ') i++;//可能一直为空或者前面若干都是 空格,处理空格
	if (i >= len) return 0;//一直为空则返回0
	if (str[i] == '-') { flag = -1; singal++; ++i; }//符号判断,同时千万记得 ++i
	if (str[i] == '+') { singal++; ++i; }//正号判断 ,++ i
	if (singal > 1) return 0;//如果出现两个符号,则是不合法的数字表达了 -+45这样的数字


	for (; i < len; ++i) {
		if (str[i]<'0' || str[i]>'9') return 0;// 是否有不合法数字出现 比如12a454
		else {
			num = num * 10 + str[i] - '0';
			if (num >= INT_MAX && flag==1) return INT_MAX;//注意这里的表达 输入如果是 INT_MAX也就是 2147483647 ,就还好
			if (num > INT_MAX && flag==-1) return INT_MIN;//但是如果输入是 INY_MIN 也就是 -2147483647-1 = -2147483648的话,
															// num因为是正数表达,所以必须num>INT_MAX才能正确判断了
		}

	}
	
	return num*flag;
}
二刷:
1、这种做法更加稳妥,

运行时间:2ms 占用内存:376k

    int StrToInt(string str) {
        int len = str.size();
        if(len == 0) return 0;
        int i = 0,flag = 1,isSignal = 0;
        long res = 0;
        while(i<len && str[i] == ' ') i++;//首先跳过全部的空格
        if(i >= len) return 0;//全部都是空格也不行
        while(i<len && (str[i] == '-' || str[i] == '+'))  {//判断标志位
            if(str[i] == '-') flag = -1;
            i++;
            isSignal++;
            if(isSignal > 1) return 0;//不能出现两个标志位
        }

        for( ; i < len; ++i){
            if(str[i]>'9' || str[i]<'0') return 0;
            res = res*10 + str[i] - '0';
            if(res > INT_MAX && flag == 1) return INT_MAX;
            if(res > INT_MAX+1 && flag == -1)  return INT_MIN;// INT_MAX+1会溢出  ,将1移到左边去就可以了  
            
        }
        
        return flag * res;
    }
2、考虑负数溢出情况

运行时间:2ms 占用内存:492k

    int StrToInt(string str) {
      	int len = str.size();
	if (len == 0) return 0;
	int i = 0, flag = 1, isSignal = 0;
	long res = 0;
	while (i < len && str[i] == ' ') i++;//首先跳过全部的空格
	if (i >= len) return 0;//全部都是空格也不行
	while (i < len && (str[i] == '-' || str[i] == '+')) {
		if (str[i] == '-') flag = -1;
		i++;
		isSignal++;
		if (isSignal > 1) return 0;//不能出现两个标志位
	}

	for (; i < len; ++i) {
		if (str[i] > '9' || str[i] < '0') return 0;
		res = res * 10 + str[i] - '0';  
		if (res > INT_MAX && flag == 1) return 0;//正数溢出
		if (res-1 > INT_MAX  && flag == -1)  return 0;//负数溢出,这个时候可以将 1 移到左边来,INT_MIN = -1 - 2的31次方 是比INT_MAX的绝对值大一的
		 
	}

	return flag * res;
    }

美女帅哥们如果觉得写的还行,有点用的话麻烦点个赞或者留个言支持一下阿秀~
如果觉得狗屁不通,直接留言开喷就完事了。

需要该笔记PDF版本的去个人公众号【拓跋阿秀】下回复“阿秀剑指offer笔记”即可。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拓跋阿秀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值