【LeetCode #8 题解】 字符串转换整数 (atoi)
发布日期:2021-06-29 14:52:36 浏览次数:3 分类:技术文章

本文共 3337 字,大约阅读时间需要 11 分钟。

一、题目:字符串转换整数 (atoi)

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。

假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

本题中的空白字符只包括空格字符 ’ ’ 。

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−2^31, 2^31 − 1]。如果数值超过这个范围,请返回 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31) 。
在这里插入图片描述

三、 题解一

#define INT_MAX  2147483647        #define INT_MIN  -2147483648   int myAtoi(char * str){
char *p = str, *p0 = str; int result = 0; int temp = 0; // 找到第一个非空字符 // 如果是非数字 while( *p != '\0' && ( *p <= '0' || *p > '9')){
// 如果找到第一个是负号,此时等于 -1 temp = *(p+1); if(*p == '-' && temp != '\0' && temp >='0' && temp <= '9'){
result = -1; }else if( *p!=' ' && *p != '0' && !( *p == '+' && temp >='0' && temp <= '9' ) ){
return 0; } // 针对 +0 1234 情况 if((*p=='+' || *p=="-" || *p=='0') && temp == ' ') {
return 0; } // 针对 0-1 情况 if( *p=='0' && (temp == '+' || temp == '-' || temp==' ') ) return 0; p++; } // 针对 -1 的情况,先乘第一个数字 if(*p > '0' && *p<='9'){
result = result >= 0 ? (*p) - 48 : -1 * ((*p) - 48); p++; } // 当退出前面的while 时,说明找到了第一个数字字符 while( *p >= '0' && *p<='9' && *p!='\0'){
temp = result >= 0 ? (*p) - 48 : -1 * ((*p) - 48); if( result > 0 && result > INT_MAX/10 || (result == INT_MAX/10 && temp > 7)) return INT_MAX; if( result < 0 && result < INT_MIN/10 || (result == INT_MIN/10 && temp < -8 )) return INT_MIN; result = result * 10 + temp ; p++; } return result;}

三、优化后的题解

在前面的解法中,考虑比较多,但题目情况没这么多,不考虑 数字在字母中间等等情况,

所以判断条件,可以简化如下:

#define INT_MAX  2147483647        #define INT_MIN  -2147483648   int myAtoi(char * str){
char *p = str; int result = 0, temp = 0, sign = 0; // 0 正数,1 负数 // 先跳过空格 while(*p == ' ') p++; // 判断符号 if( *p == '+' || *p == '-' ){
sign = *p=='+' ? 0 : 1; p++; } // 提取数字 while( *p!='\0' && *p >= '0' && *p<='9'){
temp = (int) ((*p) - '0'); // 最大及最小判断,最大末尾数>7 ,最小末尾数<8 if( result > INT_MAX/10 || (result == INT_MAX/10 && temp >= (7+sign))) return sign ? INT_MIN : INT_MAX; result = result * 10 + temp ; p++; } return sign ? -1 * result : result;}

在这里插入图片描述

四、 leetcode 上更优秀的解法学习

如下是利用sscanf 来实现对字符串的过滤,算法简单,但有一个不好的地方就是和题目不符,

题目要求,在 32位下, long是64位。

int myAtoi(char *str){
long i = 0; int ret = sscanf(str, "%ld", &i); // 注意 读取的是字母l和字母d,不是数字1和字母d if (ret) {
if (i > INT_MAX) return INT_MAX; else if (i < INT_MIN) return INT_MIN; } return i;}
/* 方法2 */int myAtoi(char *str){
long n = 0; int sign = 0; /* 跳过空格 */ while (*str == ' ') ++str; /* 判断符号 */ if(*str == '-' || *str == '+') {
sign = (*str == '-'); ++str; } while (isdigit(*str)) {
if (10 * n + *str - '0' > INT_MAX) {
return sign ? INT_MIN : INT_MAX; //判断溢出 } n = 10 * n + *str - '0'; ++str; } return sign ? -n : n;}

转载地址:https://ciellee.blog.csdn.net/article/details/107409213 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【LeetCode #9 题解】 回文数
下一篇:进程通信方式总结与盘点

发表评论

最新留言

不错!
[***.144.177.141]2024年04月26日 19时42分25秒