Leetcode题目:https://leetcode.com/problems/string-to-integer-atoi/
Github题解 : https://github.com/gatieme/LeetCode/tree/master/008-StringToInteger
CSDN解题:http://blog.csdn.net/gatieme/article/details/51046065
题目
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.
Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.
将一个字符串表示的数字的转换成整数类型
分析
简单问题,如下代码即是主要框架
for (; *str != '\0'; str++)
{
if ('0' <= *str && *str <= '9')
{
value *= 10;
value += *str - '0';
#ifdef DEBUG
printf("value = %lld\n", value);
#endif
}
else
{
break;
}
}
但是需要注意的问题,
- 前面的空白字符
// 排除前导的空格
while (*str == ' ' || *str == '\n' || *str == '\t') // 排除前导的空格
{
str++;
}
- 数字前面可能有符号位+/-
// 判断符号位+ -
if (*str == '+')
{
str++;
}
else if (*str == '-')
{
str++;
minus = true;
}
- overflow问题
我的解决方案是在循环的过程中,只要一发生溢出就结束
// 解决OVER_FLOW的问题
// INT_MAX 2147483647
// INT_MIN -2147483648 minus = true
if((minus == true && value > (unsigned long)(INT_MAX) + 1) // 负数绝对值最大为INT_MAX + 1
|| (minus == false && value > INT_MAX)) // 正数最大值为INT_MAX
{
debug <<value <<", " <<INT_MAX + 1 <<endl;
debug <<"to max than int" <<endl;
break;
}
如果最后再判断可能出现的问题,因为不管我们value用什么保存,long,long long,他们都有表示范围,都存在溢出,字符串过长时都会溢出,溢出后可能会发生截断,或者甚至读取成一个负数,那么我们循环结束后再判断就不可行。
代码
/*************************************************************************
> File Name: atoi.c
> Author: GatieMe
> Mail: gatieme@163.com
> Created Time: 2016年04月02日 星期六 22时22分06秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#define __tmain main
int myAtoi(const char *str)
{
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (str == NULL)
{
return 0;
}
// 排除前导的空格
while (*str == ' ' || *str == '\n' || *str == '\t') // 排除前导的空格
{
str++;
}
bool minus = false;
// 判断符号位+ -
if (*str == '+')
{
str++;
}
else if (*str == '-')
{
str++;
minus = true;
}
long long int value = 0;
for (; *str != '\0'; str++)
{
if ('0' <= *str && *str <= '9')
{
value *= 10;
value += *str - '0';
#ifdef DEBUG
printf("value = %lld\n", value);
#endif
}
else
{
break;
}
// 解决OVER_FLOW的问题
// INT_MAX 2147483647
// INT_MIN -2147483648 minus = true
if((minus == true && value > (unsigned long)(INT_MAX) + 1) // 负数绝对值最大为INT_MAX + 1
|| (minus == false && value > INT_MAX)) // 正数最大值为INT_MAX
{
break;
}
}
if (minus == true)
{
value = -value;
}
if (value > INT_MAX)
{
value = INT_MAX;
}
else if (value < INT_MIN)
{
value = INT_MIN;
}
return (int)value;
}
int __tmain(void)
{
printf("%d", myAtoi("9223372036854775809"));
return EXIT_SUCCESS;
}