时间:2015年6月14日,今天我开始写下我的第一篇博客,正如我博文的简介:记录想法的美好瞬间,也秉持着开源、共享的精神,我会继续坚持的走下去,去记录我成长的点点滴滴。好了,废话不说了,进入主题:如何实现atoi函数。
1、Myatoi思路分析
atoi函数是实现将字符串转化为整数的过程。但是,字符串里可以包含多种字符,比如数字、字母、空格和特殊字符(‘-’、‘+’、‘?’、‘*’等等)这4中字符。所以经过4种字符的组合,字符串就变得复杂,那么转化为整数的过程也变得复杂。下面重点介绍atoi函数的实现思想。
在介绍想法前,先看些例子。如:1)字符串的首字符是空格。“ 1”--->1,说明空格是可以忽略的;
2)字符串的首字符除了‘-’与‘+’外的特殊字符。如“?45”--->0;
3)字符串的首字符非数字的情况,需要分成4种情况进行讨论。说明:本文设置flag为控制位,flag=-1为负数,flag=1为正数。
- 首字符既不是‘-’,也不是‘+’,此时return 0(即字符串的转化的整数为0,下面不再说明);
- 首字符是‘-’或‘+’,且下个字符是满足以下3种情况的其中一种情况(不是数字、是空格、是特殊字符),则return 0;
- 首字符是‘-’,且下个字符是数字,设置flag=-1;如:"-34k7"--->-34
- 首字符是‘+’,且下个字符是数字,设置flag=1;如:"+34k7"--->34
4)字符串的次首字符是数字,且满足flag=-1;如:"-3k57"--->-3
5)字符串的首字符是数字,且满足flag=0或者1;如:"3k57"--->3
2、整数溢出
在16位的系统中,int为2字节,取值范围-32768~32767;在32位的系统中,int为4字节,取值范围
-2147483648~2147483647。所以,当你超出取值边界时,就会发生整数溢出现象。
本代码就因为未考虑到整数溢出问题,所以用单独的篇幅加以介绍和解决。
上面出现错误的提示。当输入“2147483648”字符串时,由于超出了边界2147483647即发生整数溢出,所以输出-2147483648,但是期望的是当发生溢出时,输出边界值。下面,通过一段代码解决这个问题。
<span style="font-size:12px;">#include <stdio.h>
#include <iostream>
const int P_a=2147483647;//consider int overflow
const int N_a=-2147483648;
using namespace std;
int main()
{
int n;
int dis;
scanf("n is %d\n",&n);//int:-2147483648 ~ 2147483647 consider overflow
dis=n-P_a;
cout<<dis<<endl;
if (dis>0)
{
cout<<P_a;
return 0;
}
else
{
cout<<n;
return 0;
}
}</span>
3、Myatoi源码
看完上面的思路,是不是有点晕,换做我也是,但是没关系,只有理解个大概就行,具体理解还得需要对照源代码进行分析,才能理解透彻。下面贴出Myatoi源码,已经被accepted.
#define P_a 2147483647//consider int overflow
#define N_a -2147483648
int myAtoi(char* str) {
//count the length of string
char *c_str=str;
int len=0;
int flag=0;//control bit
int count=0;//how many numbers in memory
int sum=0;
int dis;
int *num,*num_buf;
while(*c_str!='\0')
{
len++;
c_str++;
}
c_str=str;//reset
//open memory to store convert number
num=(int *)malloc(len*sizeof(int));
num_buf=num;
for( ; *c_str!='\0'; c_str++)
{
if(*c_str!='+' && *c_str!='-' && ispunct(*c_str) && flag==0)
{
return 0;
}
else if(isspace(*c_str) && flag==0)
{
continue;
}
else if(!isdigit(*c_str))
{
if(*c_str!='-' && *c_str!='+' && flag==0)
{
return 0;
}
else if((*c_str=='-' || *c_str=='+') && flag==0 &&(!isdigit(*(c_str+1)) || ispunct(*(c_str+1)) || isspace(*(c_str+1)) ) )
{
return 0;
}
else if(*c_str=='-' && isdigit(*(c_str+1)) && flag==0 )
{
flag=-1;//negtive number
continue;
}
else if(*c_str=='+' && isdigit(*(c_str+1)) && flag==0 )
{
flag=1;//positive
continue;
}
}
else if(isdigit(*c_str) && flag==-1)//negtive option
{
*num=*c_str-'0';
num++;
count++;
if(!isdigit(*(c_str+1)) || isspace(*(c_str+1)) || ispunct(*(c_str+1)) )
{
break;
}
else
{
continue;
}
}//positive option
else if(isdigit(*c_str))
{
*num=*c_str-'0';
num++;
count++;
flag=1;
if(!isdigit(*(c_str+1)) || isspace(*(c_str+1)) || ispunct(*(c_str+1)) )
{
break;
}
else
{
continue;
}
}
}
num=num_buf;
//end
//store numbers successfully
//consider overflow option
if(count>10)
{
if(flag>0)
{
return P_a;
}
else if(flag<0)
{
return N_a;
}
}
else if(count==10 && *num>2)
{
if(flag>0)
{
return P_a;
}
else if(flag<0)
{
return N_a;
}
}
//below is 1)count=10 *num<=2 2)count<10
for(int i=1; i<=count; i++)
{
sum=sum+(*num)*pow(10,count-i);
num++;
}
if(flag<0)
{
if((-sum)!=0)
{
dis=(-sum)-N_a;
if(dis<=0)
{
return N_a;
}
else if(dis>0)
{
return -sum;
}
}
else
{
return sum;
}
}
else if(flag>0)
{
dis=sum-P_a;
if(dis>=0)
{
return P_a;
}
else if(dis<0)
{
return sum;
}
}
return sum;//flag=0; spcae
//over
4、总结
这是我的第一篇博客,对atoi函数也是自己的一点想法,仅供参考。写的不好的地方,请大家在评论里提意见。最后,希望自己能够坚持,养成写博客的习惯,记录自己IT路成长的点点滴滴。