Leetcode Q8

来源:互联网 发布:linux vim 命令大全 编辑:程序博客网 时间:2024/04/30 23:29

做完这题,我有种想毁灭世界的冲动。。。程序员的世界果然到处是奇葩啊!!!抓狂抓狂抓狂如果有完全独立思考能一次通过所有测试用例的大神,请收下我的膝盖。。

先看原题:

Implement atoi to convert a string to an integer.

不看后面的提示和注释,题目就一句话。。这是要闹哪样。。好吧,我承认,这题目看起来还是相当简单的,不就是把字符串转换为整数嘛,把字符串每个字符输出然后。。嗯。。。作为一个多多少少涉足编程四、五年的小菜来说,细思恐极啊!字符的范围太广了,包括字符、符号、数字等,不是所有字符串都可以转为整数的,也不是含有非数字的字符串不能被转为数字的。。。原来这题难度在这啊(题目提示也给出了此题难点,并在隐藏文本中给出了一些特殊情况的定义和解释,是你自己为了装X不看),于是,艰难的测试->修改代码->测试->修改代码……的过程开始了。。。

此题的解决思路很简单,就是获取字符串每个字符 -> 分析各个字符的情况并给出处理方法 -> 获取整数各位数字 -> 重构整数 -> 判断越界 -> 输出,我就不赘述了,下面重点分析大家怎样考虑问题和可能会漏掉的一些情况及相应处理方法。

(下面的一句话为了突出特意单独成段)

本文只提供我自己解决问题的思路,不是大神的分析贴,除了最后通过的代码其余代码都是有问题的,不喜勿喷!

另外,为了让大家也能先自己独立思考所有可能的情况和对应的解决方法,我把leetcode给出的提示放在本文的最后。

第一阶段:

int myAtoi(string str) {        int len = str.length();    vector<int> x;    if(len<=0 || len > 11){cout<<"error!"<<endl;return 0;}    for(int i = 0; i< len; i++){    if((str[i]<'0'||str[i]>'9') && str[i]!='-'){cout<<"error!"<<endl;return 0;}    if(str[i]=='-')    if(i>0){cout<<"error!"<<endl;return 0;}    else continue;    else     if(str[0]=='-')x.push_back((int)str[i]-48);    else x.push_back((int)str[i]-48);    }    //判断是否越界    if(x.size()>10){cout<<"out of the range of int!"<<endl;return 0;}    if(x.size()==10){    vector<int> max;    int a = INT_MAX;    while(a!=0){max.push_back(a%10);a = a/10;}    if(str[0]=='-')max[0]++;    for(int i = 0 ;i<10;i++){    if(x[i]==max[9-i])continue;    else     if(x[i]<max[9-i])break;    else {cout<<"out of the range of int!"<<endl;return 0;}    }    }    //重构    int integer = 0;    for(int i = 0; i<x.size();i++)integer = integer*10 + x[i];    if(str[0]=='-')integer = -integer;    return integer;    }
首先,我考虑到整型的长度最多是10位,考虑到符号最多11位,所以其他情况直接输出0,再考虑字符串可能含有字符、符号、数字等多种情况,需要对这些情况进行分类讨论,如果出现字母和除了负号以外的符号,则直接输出0,否则如果是负号,在第一位就继续访问下面的元素,在数字后面就直接输出0,如果不是负号,那就剩数字了,压入vector,直到整型数串被全部获取,再类似Leetcode Q7的做法进行重构和判断越界,并对相应情况进行处理即可(上一篇已经说的很清楚了,这里就不赘述了)。

按理说我考虑到了字符串位数、字符类型的不同处理、负号的存在和越界情况的处理,已经很全面了,可是。。。结果还是wrong answer了,第一个反例就是"+123"。。。竟然+也可以作为正确的整型数前的符号存在(原谅我孤陋寡闻。。。),三观被刷新了,好吧,你说是就是吧,于是我又添加了对加号的处理,第二阶段代码如下:

int myAtoi(string str) {        int len = str.length();    vector<int> x;    if(len<=0 || len > 11){cout<<"error!"<<endl;return 0;}    for(int i = 0; i< len; i++){    if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+'){cout<<"error!"<<endl;return 0;}    if(str[i]=='-'|| str[i]=='+')    if(i>0){cout<<"error!"<<endl;return 0;}    else continue;    else x.push_back((int)str[i]-48);    }  <span style="white-space:pre"></span>……    }
现在应该没问题了吧。。结果。。leetcode告诉我,像“     123”这样的一堆空格+数字的也算是整型数。。三观又被刷新了。。好吧,那就加个条件判断在没出现数字之前出现空格就忽略好了,代码如下:

 int myAtoi(string str) {        int len = str.length();    vector<int> x;    if(len<=0 || len > 11){cout<<"error!"<<endl;return 0;}    for(int i = 0; i< len; i++){        if(str[i] == ' ')continue;    if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+'){cout<<"error!"<<endl;return 0;}    if(str[i]=='-'|| str[i]=='+')    if(i>0){cout<<"error!"<<endl;return 0;}    else continue;    else x.push_back((int)str[i]-48);    }  ……    }
结果。。又错。。因为没考虑数字首位是0的情况。。这个我在Q7都考虑到了,Q8没考虑到。。扇自己两巴掌。这样长度就不一定是最长11位了,修改后代码如下:

int myAtoi(string str) {        int len = str.length();    vector<int> x;    if(len==0){cout<<"error!"<<endl;return 0;}    for(int i = 0; i< len; i++){    //整数数字串前有空格也认为是整数    if(str[i] == ' ')continue;    //整数数字串前有0保留首位非0的整数    if(str[i] == '0' && x.size() == 0)continue;    if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+'){cout<<"error!"<<endl;return 0;}    //整数数字串前有正号也认为是整数    if(str[i]=='-'|| str[i]=='+')    if(x.size()!=0){cout<<"error!"<<endl;return 0;}    else continue;    else x.push_back((int)str[i]-48);    }    ……    }

错!这次是忘了处理+-同时出现的情况,这也是不能转换的。修改修改!加个flag判断正负就好了~

int myAtoi(string str) {       int len = str.length();    int flag = 0;//判别整数是有符号(+/-)整数还是无符号整数    vector<int> x;    if(len==0){cout<<"error!"<<endl;return 0;}    for(int i = 0; i< len; i++){    //整数数字串前有空格也认为是整数    if(str[i] == ' ')continue;    //整数数字串前有0保留首位非0的整数    if(str[i] == '0' && x.size() == 0)continue;    if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+'){cout<<"error!"<<endl;return 0;}    //整数数字串前有正号也认为是整数    if(str[i]=='-'|| str[i]=='+'){    if(flag != 0){cout<<"error!"<<endl;return 0;}    if(str[i]=='-')flag = -1;    else flag = 1;    if(x.size()!=0){cout<<"error!"<<endl;return 0;}    else continue;    }    else x.push_back((int)str[i]-48);    }……    }

还错。。。leetcode告诉我“   -0a123”虽然不是整型数,但是要保留a前面是整型数的部分。。好吧。。我被折磨够了。。那就把遇到a然后return 0改为break,好了,然后输出a前面的整型数。这里要注意,前面如果有0,也是要输出的,这样在判断字符是0还要同时保证是后面有非0数的首位的0,干脆将判断放到后面,for循环专门用于输出字符串中符合要求的数字(包括首位0),同时,要注意空格和a这样的字符一样,即先有数字然后再遇到空格就要停止遍历了。代码如下:

int myAtoi(string str) {      int len = str.length();    int flag = 0;//判别整数是有符号(+/-)整数还是无符号整数    vector<int> x;    if(len==0)return 0;    for(int i = 0; i< len; i++){    //整数数字串前有空格也认为是整数,但空格在数字间就保留空格前是整数的部分    if(str[i] == ' '){    if(x.size()==0 && flag == 0)continue;    else break;    }    //整数数字串前有正号也认为是整数    if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+')break;    if(str[i]=='-'|| str[i]=='+'){    if(flag != 0)break;    if(str[i]=='-')flag = -1;    else flag = 1;    if(x.size()!=0)break;    else continue;    }    else x.push_back((int)str[i]-48);    }    //判断是否为空    if(x.size()==0)return 0;    //判断首位是否为0    if(x.size()>1){    while(x[0]==0)x.erase(x.begin());    }    //判断是否越界    if(x.size()>10)return 0;    if(x.size()==10){    vector<int> max;    int a = INT_MAX;    while(a!=0){max.push_back(a%10);a = a/10;}    if(flag == -1)max[0]++;    for(int i = 0 ;i<10;i++){    if(x[i]==max[9-i])continue;    else     if(x[i]<max[9-i])break;    else return 0;    }    }    //重构    int integer = 0;    for(int i = 0; i<x.size();i++)integer = integer*10 + x[i];    if(flag == -1)integer = -integer;    return integer;    }

改到现在,我已经头晕眼花了。。结果又错!这次竟然错在数组越界的输出值上,鬼知道越界了还要输出临界值而不是报错输出0,我就不贴代码了,把越界的正数输出2147483647,负数输出-2147483648即可。最后,终于accepted了,完整正确代码如下:

#include "stdafx.h"#include <iostream>#include <string>#include <limits.h>#include <math.h>#include <vector>using namespace std;int myAtoi(string str) {int len = str.length();int flag = 0;//判别整数是有符号(+/-)整数还是无符号整数vector<int> x;if(len==0)return 0;for(int i = 0; i< len; i++){//整数数字串前有空格也认为是整数,但空格在数字间就保留空格前是整数的部分if(str[i] == ' '){if(x.size()==0 && flag == 0)continue;else break;}//整数数字串前有正号也认为是整数if((str[i]<'0'||str[i]>'9') && str[i]!='-' && str[i]!='+')break;if(str[i]=='-'|| str[i]=='+'){if(flag != 0)break;if(str[i]=='-')flag = -1;else flag = 1;if(x.size()!=0)break;else continue;}else x.push_back((int)str[i]-48);}//判断是否为空if(x.size()==0)return 0;//判断首位是否为0if(x.size()>1){while(x[0]==0)x.erase(x.begin());}//判断是否越界if(x.size()>10){if(flag == -1)return -2147483648;else return 2147483647;}if(x.size()==10){vector<int> max;int a = INT_MAX;while(a!=0){max.push_back(a%10);a = a/10;}if(flag == -1)max[0]++;for(int i = 0 ;i<10;i++){if(x[i]==max[9-i])continue;else if(x[i]<max[9-i])break;else if(flag == -1)return -2147483648;else return 2147483647;}}//重构int integer = 0;for(int i = 0; i<x.size();i++)integer = integer*10 + x[i];if(flag == -1)integer = -integer;return integer;}int _tmain(int argc, _TCHAR* argv[]){string s = "  - 321";int x = myAtoi(s);cout<<"transform the string \""<<s.c_str()<<"\" to: "<<x<<endl;return 0;}
总结:

1.考虑问题有时候总会有遗漏,调bug时要有一颗屡败屡战的强大内心!

最后,再看看题目给出的隐藏提示,基本上涵盖了以上所有考虑的内容。

Requirements for atoi:

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

0 0
原创粉丝点击