Leetcode刷题之c++实现atoi函数

最近在刷Leetcode的题,在此记录一下如何利用c++实现atoi函数,atoi函数能够将一个字符串转换成整数,实现要求如下:

  1. 忽略字符串前面的空格,直到遇到第一个非空格的字符,从该字符开始判断,首字符可以是’+’,’-’,和0-9之间的数字,例如
    “123” ---------> 123
    " 123" ---------> 123
    " +123aa" ---------> 123
    " 000123aa df is " ---------> 123
    " -123 " ---------> -123
    " -123 xx" ---------> -123

  2. 若第一个非空格的字符不是一个有效的数字,若该字符串为空或者是只包含空格,就不进行转换,返回0,例如
    “ ” ---------> 0
    “ asdd is dd " ---------> 0

  3. 用于转换的整数最多为32位,其范围是[pow(-2,31),pow(2,31)-1],若超出这个范围,返回值分别为INT_MIN(pow(-2,31))和INT_MAX(pow(2,31)-1),例如
    ”200000000000000000000000“---------> INT_MAX
    " -12345678901234111edddfss deff "---------> INT_MIN

  4. “-000000123” ---------> -123
    “00000123zza” ---------> 123

题目本身不难,但是需要考虑的点比较多,作为萌新码农一只,还是花了一点时间来实现的,看来还是要多加练习。具体实现如下,可以根据注释理解过程

#include<vector>
#include<algorithm>
#include <math.h>

using namespace std;

class Solution {
public:
	int myAtoi(string str) {
		int i = 0;
		vector<int> rst;
		long long int out = 0;
		int count = 0;
		//下述首字符指的是首个不是空格的字符
		while ((str[i] > 57) || (str[i] < 48))  //在首字符不是有效数字的情况下
		{
			if (str[i] == 45)  //若首字符是减号
			{
				if ((str[i + 1] != 32)&& (str[i + 1] != 45) && (str[i + 1] != 43)) //后一个字符不是空格、减号、加号
				{
					i++;   //判断下一个字符
				}
				else
				{
					return 0;  //符合上述条件2,返回0
				}
				
			}
			else if (str[i] == 32) //若首字符是空格
			{
				i++;//判断下一个字符
			}
			else if (str[i] == 46) //若首字符是小数点,直接转换成0
			{
				return 0;
			}
			else if ((str[i] == 43) && (str[i + 1]<58) && (str[i + 1]>47))//若首字符是加号,后一个字符是有效数字
			{
					i++; //判断下一个字符
			}
			else //否则,返回0
			{
				return 0;
			}
		}
		for (int j = i; j < str.size(); j++)//若首字符是有效数字
		{
			if ((str[j] == 46)) //若有效数字后面包含小数点,则舍弃小数点后面的数字
			{
				break;
			}
			if ((str[j] <= 57) && (str[j] >= 48))  //若首字符是有效数字
			{
				count++; //计数
				int ddd = str[j];
				rst.push_back(str[j] - 48); //把有效数字添加在rst向量中
			}
			else //若有效数字后面包含的不是有效数字,则舍弃后面的字符
			{
				break;
			}
		} 
		for (int n = 0; n < rst.size(); n++)
		{
			if (i > 0)//若字符串中第一个数字不是有效数字
			{
				if (str[i - 1] == 45) //若首字符前面有‘-’号,负数
				{
					int v = 0;
					while (rst[v] == 0)//针对上述条件4
					{
						v++;
						if (v >= rst.size())  
							break;  //找出第一个非0的数字
					}
					if (v > 0)  //若首字符是0
					{
						if ((count - v > 9))  //若有效数字的个数大于9,超出范围
							return INT_MIN; //返回INT_MIN
					}
					else  //若首字符不是0
					{
						if ((count - 1 > 9))//若有效数字的个数大于9,超出范围
							return INT_MIN;//返回INT_MIN
					}

					out += (rst[n] * pow(10, count - n - 1))*(-1); // 计算输出值
					if (out < pow(-2, 31)) //若是输出值超出范围
					{
						return INT_MIN;//返回INT_MIN
					}
				}
				else if (str[i - 1] == 43) //若首字符前面有‘+’号,正数,过程同上
				{
					int v = 0;
					
					while (rst[v] == 0)
					{
						v++;
						if (v >= rst.size())
							break;
					}

					if (v > 0)
					{
						if ((count - v > 9))
							return INT_MAX;
					}
					else
					{
						if ((count - 1 > 9))
							return INT_MAX;
					}
					out += (rst[n] * pow(10, count - n - 1));
					if (out > pow(2, 31) - 1)
					{
						return INT_MAX;
					}
				}
				else//若首字符前面全是空格,没有‘+’或’-‘
				{
					int v = 0;
					while (rst[v] == 0)//判断首字符是否为0,上述条件4 
					{
						v++;
						if (v >= rst.size())
							break;
					}
					if (v > 0)
					{
						if ((count - v > 9))
							return INT_MAX;
					}
					else
					{
						if ((count - 1 > 9))
							return INT_MAX;
					}
				

					out += (rst[n] * pow(10, count - n - 1));
					if (out > pow(2, 31) - 1)
					{
						return INT_MAX;
					}
				}
				
			}
			else //若字符串中第一个字符就是有效数字
			{
				int v = 0;
				while (rst[v] == 0)//判断首字符是否为0,上述条件4
				{
					v++;
					if (v >= rst.size())
						break;
				}

				if (v > 0)
				{
					if((count - v > 9))
						return INT_MAX;
				}
				else
				{
					if ((count - 1 > 9))
						return INT_MAX;
				}

				out += rst[n] * pow(10, count - n - 1);
				if (out > pow(2, 31) - 1)
				{
					return INT_MAX;
				}
			}
		}
		return out;
	}
};

结果运行如下:
在这里插入图片描述
运行速度是很快的,但是占用内存较大,后续需要再看看有没有可以减小内存的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值