Leetcode 8:String to Integer (atoi)

Description:

  请你来实现一个 atoi 函数,使其能将字符串转换成整数。
  首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
  当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
  该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
  注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
  在任何情况下,若函数不能进行有效的转换时,请返回 0。

Note:

  • 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [231,2311] 。如果数值超过这个范围,请返回 INT_MAX ( 2 31 − 1 2^{31}-1 2311) 或 INT_MIN ( − 2 31 -2^{31} 231) 。

Example

Input: "42"
Output: 42
Input: "   -42"
Output: -42
Input: "4193 with words"
Output: 4193
Input: "words and 987"
Output: 0
Input: "-91283472332"
Output: -2147483648

题目之我见

  题目的要求类似于 string 类中 stoi() 函数的实现,但是又比 stoi() 函数考虑到的状况更多,比如可能转换后整数会远远超出范围,或者 stoi() 根本无法转换,所以 solution 1的思路就是基于 stoi() 函数,再对其他 stoi() 不能处理的情况进行处理。

Solution 1(函数实现在 26 到 62 行)

#include <iostream>
#include <climits>	// INT_MAX, INT_MIN
#include <stdexcept>	// try,catch

using namespace std;

int myAtoi(string str);

int main(void)
{
	string s = "";
	string s1 = "+; 1";
	string s2 = "+1-";
	string s3 = " -222222222222222222222";
	string s4 = "-00";

	cout << myAtoi(s) << endl;
	cout << myAtoi(s1) << endl;
	cout << myAtoi(s2) << endl;
	cout << myAtoi(s3) << endl;
	cout << myAtoi(s4) << endl;

	return 0;
}

int myAtoi(string str)
{
	int res;

	if (str.empty())
		return 0;
	else 
	{	// 其实可以使用 find_first_not_of 优化
		while (!str.empty() && str.at(0) == ' ') {str.erase(0, 1);}	// 去除串首空格符
		
		if (str.empty())
			return 0;
		else if (!isdigit(str.at(0)) && str.at(0) != '+' && str.at(0) != '-') 
			return 0;		// 第一个非空字符不是数字也不是'+' / '-'
		else if (str == "+" || str.at(0) == '+'&& str.length()>1 && !isdigit(str.at(1)))
			return 0;		// 第一个非空字符是 '+',但第二个字符不是数字
		else if (str == "-" || str.at(0) == '-'&& str.length()>1 && !isdigit(str.at(1)))
			return 0;		// 第一个非空字符是 '-',但第二个字符不是数字
		else
		{
			try
			{
				res = stoi(str);
			}
			catch (std::out_of_range &exc)	// 异常处理,若果抛出异常说明转换后整数已超出 int 范围
			{								// 这时在对异常进行处理
				//std::cerr << exc.what() << endl;
				if ('-' == str.at(0))
					return INT_MIN;
				else
					return INT_MAX;
			}

			return res;
		}
	}
}
复杂度

在这里插入图片描述
我觉得海星。
自己做完之后又去看了 discussion,几乎全是对字符串进行逐字符处理(逃,还是我太赖了。。

Solution 2:

int myAtoi(string str) 
{
	long res = 0;
	int sign = 1;
	size_t index = 0;
	
	if(str.find_first_not_of(' ') != string::npos) 
		index = str.find_first_not_of(' ');
	if(str[index] == '+' || str[index] == '-') 
		sign = str[index++] == '-' ? -1 : 1;
	
	while(index<str.length() && isdigit(str[index])) 
	{
		res = res * 10 + (str[index++] - '0');
		if(res*sign > INT_MAX) 
			return INT_MAX; //Check for INT_MAX & INT_MIN bounds
		if(res*sign < INT_MIN) 
			return INT_MIN;
	}
	return res * sign;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值