最近在刷Leetcode的题,在此记录一下如何利用c++实现atoi函数,atoi函数能够将一个字符串转换成整数,实现要求如下:
-
忽略字符串前面的空格,直到遇到第一个非空格的字符,从该字符开始判断,首字符可以是’+’,’-’,和0-9之间的数字,例如
“123” ---------> 123
" 123" ---------> 123
" +123aa" ---------> 123
" 000123aa df is " ---------> 123
" -123 " ---------> -123
" -123 xx" ---------> -123 -
若第一个非空格的字符不是一个有效的数字,若该字符串为空或者是只包含空格,就不进行转换,返回0,例如
“ ” ---------> 0
“ asdd is dd " ---------> 0 -
用于转换的整数最多为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 -
“-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;
}
};
结果运行如下:
运行速度是很快的,但是占用内存较大,后续需要再看看有没有可以减小内存的方法。