[leetcode 8] String to Integer (atoi)

本文介绍了一种将字符串转换为整数的有效方法,重点讨论了如何处理各种边界情况,包括空格、符号和非数字字符,同时解决了整数溢出问题。

题目:

Implement atoi to convert a string to an integer.

Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.

Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

Requirements for atoi:

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. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

思路:

1.题目本身比较简单,即将一个字符串转换成数字;
2.我们知道,将一个char字符强制转换成int型,即可获取该字符的acsll码,如(int)'0'=48,(int)'9'=57,基于此,我们可以判断一个字符的acsll码判断该字符是否在48--57的范围内,从而判断该字符的值是否为数字,并可根据s[i]-(int)'0'得到s[i]的值(若s[i]='1',则s[i]-(int)'0'=1,1即为s[i]的字面值);
3.第2步即为本题的主要思路,然后需要考虑的是处理不同输入,首先一个字符串可能前一段子串为空,如“    123”,那么首先需要将指针移动至1处;
4.之后可以从1处开始遍历字符串,有两个特殊字符,为‘-’和'+',若这两个字符出现在有效字符串的最前面,则其表示该数的正负,若出现在其他位置,则无意义,若有效字符串的起始处出现上述两个字符之一,则可设一flag,表示该数的正负,接着从后面继续遍历字符串;
5.在遍历字符串过程中,如果遇到无效字符(如‘a’),则遍历应该终止;
6.本题需要着重考虑溢出问题,这也是困扰我时间最长的问题,在构造结果数字的过程中,需要做两个操作,一个是result*10,一个是result*10+(int)s[i]-(int)'0',对于加法而言,很容易判断溢出,若两个正数x+y<x,则必然发生溢出,而乘法溢出这样很难判断(如:若大于100则溢出,12*10溢出后结果为20,依旧大于12,而11*10溢出后结果为10,小于11,所以如果设result为int型,根据result无法判断是否溢出),解决方法是设result为long long型,因为int型用32bit存储,而long long型用64bit存储,根据64位的result与32位存储最大值INT_MAX比较,很容易判断乘法或者加法操作时候有溢出,所以,long long型的选取时本题的关键;
7.此外还要注意,INT_MAX与INT_MIN的绝对值不一样,由于构造result的过程中,其一直是正数,最后才设置其正负性,所以构造过程中,若发生溢出,则需通过判断flag的值决定赋给result的值(若result==INT_MAX || result==INT_MIN),则最后不为其设置正负;
8.此算法只遍历字符串一次,故其时间复杂度为O(n);

代码:

class Solution{
public:
	int atoi(string s)
	{
		int len=s.length();
		int zero=(int)'0';
		int nine=(int)'9';
		int idx=0;
		int flag=1;
		long long result=0;
		while(s[idx]==' ')
			++idx;
		for(int i=idx;i!=len;++i)
		{
			if(i==idx && (s[i]=='-' || s[i]=='+'))
			{
				if(s[i]=='-')
				{
					flag=-1;
				}
				continue;
			}
			if((int)s[i]<zero || (int)s[i]>nine)
				break;
			else
			{
		    	if((result*10+(int)s[i]-zero)>INT_MAX)
				{
					if(flag==1)
						result=INT_MAX;
					if(flag==-1)
						result=INT_MIN;
				}
				else
					result=result*10+(int)s[i]-zero;
			}
		}
		if((flag==1 && result==INT_MAX) || (flag==-1 && result==INT_MIN))
			return result;
		else
			return flag*result;
	}
};		


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值