【剑指offer】字符串转整数

转载请注明出处:http://blog.csdn.net/ns_code/article/details/28015693

题目描述:

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为一个合法或者非法的字符串,代表一个整数n(1<= n<=10000000)。

输出:

对应每个测试案例,
若输入为一个合法的字符串(即代表一个整数),则输出这个整数。
若输入为一个非法的字符串,则输出“My God”。

样例输入:
5
-5
+8
样例输出:
5
-5
8
    关于这道题目,题目本身还是不错的,真正核心的代码也就那么两行,大部分代码基本都在做非法输入的检查。

    最近做这几道题目,对九度后台的测试用例有点无语了,这道题目的测试用例应该有问题,我写的代码自己测试了很多种不同的非法输入以及合法输入,都没问题,但是在九度OJ上只有第四条测试用例通过,其他四条全部WA,害的我搞了一个晚上,后来下了个别人AC的代码,拿来测试了下,结果各种非法的输入都没处理,很多非法的输入,得到的都是些五花八门的答案。

    先贴上代码,大家帮我看下有木有没考虑到的地方:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdbool.h>  
  3. bool IsValid;  
  4.   
  5. long StrToIInt(const char *str)  
  6. {  
  7.     //非法输入  
  8.     if(str == NULL)  
  9.     {  
  10.         IsValid = false;  
  11.         return 0;  
  12.     }  
  13.   
  14.     //是否为负数  
  15.     bool IsMinus = false;  
  16.   
  17.     //跳过前面的空白字符  
  18.     while(*str == ' ')  
  19.         str++;  
  20.   
  21.     //第一个非空白字符为+号  
  22.     if(*str == '+')  
  23.         str++;  
  24.     //第一个非空白字符为-号  
  25.     else if(*str == '-')  
  26.     {  
  27.         str++;  
  28.         IsMinus = true;  
  29.     }  
  30.   
  31.     //如果只输入了空白字符、符号位,或者什么都没输入,也为非法输入  
  32.     if(*str == '\0')  
  33.     {  
  34.         IsValid = false;  
  35.         return 0;  
  36.     }  
  37.   
  38.   
  39.     //后面的输入如果合法,则转化为整数  
  40.     long num = 0;   //转化为整数后的结果  
  41.     //这样可以使类似234asd的输入也判定为合法输入,得到的结果为234  
  42.     while(*str != '\0')  
  43.     {  
  44.         //输入不在0-9之间,属于非法输入  
  45.         if(*str<'0' || *str>'9')  
  46.         {  
  47.             IsValid = false;  
  48.             return 0;  
  49.         }  
  50.         //对不包含符号位的合法输入进行转换  
  51.         num = 10*num + (*str - '0');  
  52.         str++;  
  53.     }  
  54.       
  55.     //根据符号位转换正负  
  56.     num = IsMinus ? (-1*num) : num;  
  57.     //判断是否溢出了int的范围  
  58.     if(num>0X7FFFFFFF || num<(signed int)0X80000000)  
  59.     {  
  60.         IsValid = false;  
  61.         return 0;  
  62.     }  
  63.   
  64.     //上面没有返回,则说明合法并没有发生溢出  
  65.     return num;  
  66. }  
  67.   
  68. int main()  
  69. {  
  70.     static char str[100000000];  
  71.     while(gets(str) != NULL)  
  72.     {  
  73.         IsValid = true;  
  74.         long result = StrToIInt(str);  
  75.         if(IsValid)  
  76.             printf("%ld\n",result);  
  77.         else  
  78.             printf("My God\n");  
  79.     }  
  80.     return 0;  
  81. }  

    最后查到有些人讲类似123abc这样的输入也作为合法输入,这样得到的结果是123,去掉了后面的非法字符,我就索性又把程序改了下,把这种情况纳入合法输入的范围内,改成如下代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdbool.h>  
  3. bool IsValid;  
  4.   
  5. long StrToIInt(const char *str)  
  6. {  
  7.     //非法输入  
  8.     if(str == NULL)  
  9.     {  
  10.         IsValid = false;  
  11.         return 0;  
  12.     }  
  13.   
  14.     //是否为负数  
  15.     bool IsMinus = false;  
  16.   
  17.     //跳过前面的空白字符  
  18.     while(*str == ' ')  
  19.         str++;  
  20.   
  21.     //第一个非空白字符为+号  
  22.     if(*str == '+')  
  23.         str++;  
  24.     //第一个非空白字符为-号  
  25.     else if(*str == '-')  
  26.     {  
  27.         str++;  
  28.         IsMinus = true;  
  29.     }  
  30.   
  31.     //如果只输入了空白字符、符号位,或者什么都没输入,也为非法输入  
  32. //  if(*str == '\0')  
  33. //  {  
  34. //      IsValid = false;  
  35. //      return 0;  
  36. //  }  
  37.   
  38.     //如果第一个非负号位输入的不是0-9的数字,为非法输入  
  39.     if(*str<'0' || *str>'9')  
  40.     {  
  41.         IsValid = false;  
  42.         return 0;  
  43.     }  
  44.   
  45.     //后面的输入如果合法,则转化为整数  
  46.     long num = 0;   //转化为整数后的结果  
  47.     //这样可以使类似234asd的输入也判定为合法输入,得到的结果为234  
  48.     while(*str != '\0' && *str>='0' && *str<='9')  
  49.     {  
  50.         //输入不在0-9之间,属于非法输入  
  51.     //  if(*str<'0' || *str>'9')  
  52.     //  {  
  53.     //      IsValid = false;  
  54.     //      return 0;  
  55.     //  }  
  56.         //对不包含符号位的合法输入进行转换  
  57.         num = 10*num + (*str - '0');  
  58.         str++;  
  59.     }  
  60.       
  61.     //根据符号位转换正负  
  62.     num = IsMinus ? (-1*num) : num;  
  63.     //判断是否溢出了int的范围  
  64.     if(num>0X7FFFFFFF || num<(signed int)0X80000000)  
  65.     {  
  66.         IsValid = false;  
  67.         return 0;  
  68.     }  
  69.   
  70.     //上面没有返回,则说明合法并没有发生溢出  
  71.     return num;  
  72. }  
  73.   
  74. int main()  
  75. {  
  76.     static char str[100000000];  
  77.     while(gets(str) != NULL)  
  78.     {  
  79.         IsValid = true;  
  80.         long result = StrToIInt(str);  
  81.         if(IsValid)  
  82.             printf("%ld\n",result);  
  83.         else  
  84.             printf("My God\n");  
  85.     }  
  86.     return 0;  
  87. }  
    这次居然前三个测试用例通过了,后面两个WA了,搞得我晕头转向,下载了个别人的AC代码,一眼看过去就感觉很多非法输入没有考虑到,测试了下,确实很多非法的输入,得到的结果五花八门。贴出来大家瞅瞅,分析下看是不是这道题的后台测试用例有问题。

    别人AC的代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3.    
  4. int state=0;  
  5.    
  6. long StrToInt(const char * str)  
  7. {  
  8.     long num;  
  9.     num = 0;  
  10.    
  11.     if(str!=NULL)  
  12.     {  
  13.         const char * digit = str;  
  14.    
  15.         int minus = 0;                              //判断正负(第一个字符)  
  16.    
  17.         if(*digit=='+')  
  18.         {  
  19.             digit++;  
  20.         }  
  21.         else if(*digit=='-')  
  22.         {  
  23.             minus = 1;  
  24.             digit++;  
  25.         }  
  26.    
  27.    
  28.         while(*digit!='\0')    //'\0'与'0'区别  
  29.         {  
  30.             if(*digit>='0' && *digit<='9')  
  31.                 num = 10*num+(*digit-'0');  
  32.             else  
  33.             {  
  34.                 state=1;  
  35.                 num=0;  
  36.                 break;  
  37.             }                              //输入不合法  
  38.             digit++;  
  39.             state=0;  
  40.         }  
  41.    
  42.         if(minus)  
  43.         {  
  44.             num = 0 - num;  
  45.         }  
  46.    
  47.     }  
  48.    
  49.     return num;  
  50.    
  51. }  
  52.    
  53. int main()  
  54. {  
  55.     long res;  
  56.     char st[100];  
  57.     char *p = st;  
  58.        
  59.     while(scanf("%s", p)!=EOF)       
  60.     {  
  61.         res = StrToInt(p);  
  62.    
  63.         if(state==0)  
  64.             printf("%ld\n", res);  
  65.         else if(state==1)  
  66.             printf("My God\n");  
  67.     }  
  68.    
  69.     return 0;  
  70. }  
  71. /************************************************************** 
  72.     Problem: 1508 
  73.     User: muddytu 
  74.     Language: C 
  75.     Result: Accepted 
  76.     Time:0 ms 
  77.     Memory:912 kb 
  78. ****************************************************************/  
    无力吐槽了,稀里糊涂的搞了整整一个晚上,竟然是这样的结果。我还是觉得第一次的代码是最正确的,不应该将类似123abc这样的输入纳入合法的输入范围中。



转载请注明出处:http://blog.csdn.net/ns_code/article/details/28015693

题目描述:

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为一个合法或者非法的字符串,代表一个整数n(1<= n<=10000000)。

输出:

对应每个测试案例,
若输入为一个合法的字符串(即代表一个整数),则输出这个整数。
若输入为一个非法的字符串,则输出“My God”。

样例输入:
5
-5
+8
样例输出:
5
-5
8
    关于这道题目,题目本身还是不错的,真正核心的代码也就那么两行,大部分代码基本都在做非法输入的检查。

    最近做这几道题目,对九度后台的测试用例有点无语了,这道题目的测试用例应该有问题,我写的代码自己测试了很多种不同的非法输入以及合法输入,都没问题,但是在九度OJ上只有第四条测试用例通过,其他四条全部WA,害的我搞了一个晚上,后来下了个别人AC的代码,拿来测试了下,结果各种非法的输入都没处理,很多非法的输入,得到的都是些五花八门的答案。

    先贴上代码,大家帮我看下有木有没考虑到的地方:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdbool.h>  
  3. bool IsValid;  
  4.   
  5. long StrToIInt(const char *str)  
  6. {  
  7.     //非法输入  
  8.     if(str == NULL)  
  9.     {  
  10.         IsValid = false;  
  11.         return 0;  
  12.     }  
  13.   
  14.     //是否为负数  
  15.     bool IsMinus = false;  
  16.   
  17.     //跳过前面的空白字符  
  18.     while(*str == ' ')  
  19.         str++;  
  20.   
  21.     //第一个非空白字符为+号  
  22.     if(*str == '+')  
  23.         str++;  
  24.     //第一个非空白字符为-号  
  25.     else if(*str == '-')  
  26.     {  
  27.         str++;  
  28.         IsMinus = true;  
  29.     }  
  30.   
  31.     //如果只输入了空白字符、符号位,或者什么都没输入,也为非法输入  
  32.     if(*str == '\0')  
  33.     {  
  34.         IsValid = false;  
  35.         return 0;  
  36.     }  
  37.   
  38.   
  39.     //后面的输入如果合法,则转化为整数  
  40.     long num = 0;   //转化为整数后的结果  
  41.     //这样可以使类似234asd的输入也判定为合法输入,得到的结果为234  
  42.     while(*str != '\0')  
  43.     {  
  44.         //输入不在0-9之间,属于非法输入  
  45.         if(*str<'0' || *str>'9')  
  46.         {  
  47.             IsValid = false;  
  48.             return 0;  
  49.         }  
  50.         //对不包含符号位的合法输入进行转换  
  51.         num = 10*num + (*str - '0');  
  52.         str++;  
  53.     }  
  54.       
  55.     //根据符号位转换正负  
  56.     num = IsMinus ? (-1*num) : num;  
  57.     //判断是否溢出了int的范围  
  58.     if(num>0X7FFFFFFF || num<(signed int)0X80000000)  
  59.     {  
  60.         IsValid = false;  
  61.         return 0;  
  62.     }  
  63.   
  64.     //上面没有返回,则说明合法并没有发生溢出  
  65.     return num;  
  66. }  
  67.   
  68. int main()  
  69. {  
  70.     static char str[100000000];  
  71.     while(gets(str) != NULL)  
  72.     {  
  73.         IsValid = true;  
  74.         long result = StrToIInt(str);  
  75.         if(IsValid)  
  76.             printf("%ld\n",result);  
  77.         else  
  78.             printf("My God\n");  
  79.     }  
  80.     return 0;  
  81. }  

    最后查到有些人讲类似123abc这样的输入也作为合法输入,这样得到的结果是123,去掉了后面的非法字符,我就索性又把程序改了下,把这种情况纳入合法输入的范围内,改成如下代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdbool.h>  
  3. bool IsValid;  
  4.   
  5. long StrToIInt(const char *str)  
  6. {  
  7.     //非法输入  
  8.     if(str == NULL)  
  9.     {  
  10.         IsValid = false;  
  11.         return 0;  
  12.     }  
  13.   
  14.     //是否为负数  
  15.     bool IsMinus = false;  
  16.   
  17.     //跳过前面的空白字符  
  18.     while(*str == ' ')  
  19.         str++;  
  20.   
  21.     //第一个非空白字符为+号  
  22.     if(*str == '+')  
  23.         str++;  
  24.     //第一个非空白字符为-号  
  25.     else if(*str == '-')  
  26.     {  
  27.         str++;  
  28.         IsMinus = true;  
  29.     }  
  30.   
  31.     //如果只输入了空白字符、符号位,或者什么都没输入,也为非法输入  
  32. //  if(*str == '\0')  
  33. //  {  
  34. //      IsValid = false;  
  35. //      return 0;  
  36. //  }  
  37.   
  38.     //如果第一个非负号位输入的不是0-9的数字,为非法输入  
  39.     if(*str<'0' || *str>'9')  
  40.     {  
  41.         IsValid = false;  
  42.         return 0;  
  43.     }  
  44.   
  45.     //后面的输入如果合法,则转化为整数  
  46.     long num = 0;   //转化为整数后的结果  
  47.     //这样可以使类似234asd的输入也判定为合法输入,得到的结果为234  
  48.     while(*str != '\0' && *str>='0' && *str<='9')  
  49.     {  
  50.         //输入不在0-9之间,属于非法输入  
  51.     //  if(*str<'0' || *str>'9')  
  52.     //  {  
  53.     //      IsValid = false;  
  54.     //      return 0;  
  55.     //  }  
  56.         //对不包含符号位的合法输入进行转换  
  57.         num = 10*num + (*str - '0');  
  58.         str++;  
  59.     }  
  60.       
  61.     //根据符号位转换正负  
  62.     num = IsMinus ? (-1*num) : num;  
  63.     //判断是否溢出了int的范围  
  64.     if(num>0X7FFFFFFF || num<(signed int)0X80000000)  
  65.     {  
  66.         IsValid = false;  
  67.         return 0;  
  68.     }  
  69.   
  70.     //上面没有返回,则说明合法并没有发生溢出  
  71.     return num;  
  72. }  
  73.   
  74. int main()  
  75. {  
  76.     static char str[100000000];  
  77.     while(gets(str) != NULL)  
  78.     {  
  79.         IsValid = true;  
  80.         long result = StrToIInt(str);  
  81.         if(IsValid)  
  82.             printf("%ld\n",result);  
  83.         else  
  84.             printf("My God\n");  
  85.     }  
  86.     return 0;  
  87. }  
    这次居然前三个测试用例通过了,后面两个WA了,搞得我晕头转向,下载了个别人的AC代码,一眼看过去就感觉很多非法输入没有考虑到,测试了下,确实很多非法的输入,得到的结果五花八门。贴出来大家瞅瞅,分析下看是不是这道题的后台测试用例有问题。

    别人AC的代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3.    
  4. int state=0;  
  5.    
  6. long StrToInt(const char * str)  
  7. {  
  8.     long num;  
  9.     num = 0;  
  10.    
  11.     if(str!=NULL)  
  12.     {  
  13.         const char * digit = str;  
  14.    
  15.         int minus = 0;                              //判断正负(第一个字符)  
  16.    
  17.         if(*digit=='+')  
  18.         {  
  19.             digit++;  
  20.         }  
  21.         else if(*digit=='-')  
  22.         {  
  23.             minus = 1;  
  24.             digit++;  
  25.         }  
  26.    
  27.    
  28.         while(*digit!='\0')    //'\0'与'0'区别  
  29.         {  
  30.             if(*digit>='0' && *digit<='9')  
  31.                 num = 10*num+(*digit-'0');  
  32.             else  
  33.             {  
  34.                 state=1;  
  35.                 num=0;  
  36.                 break;  
  37.             }                              //输入不合法  
  38.             digit++;  
  39.             state=0;  
  40.         }  
  41.    
  42.         if(minus)  
  43.         {  
  44.             num = 0 - num;  
  45.         }  
  46.    
  47.     }  
  48.    
  49.     return num;  
  50.    
  51. }  
  52.    
  53. int main()  
  54. {  
  55.     long res;  
  56.     char st[100];  
  57.     char *p = st;  
  58.        
  59.     while(scanf("%s", p)!=EOF)       
  60.     {  
  61.         res = StrToInt(p);  
  62.    
  63.         if(state==0)  
  64.             printf("%ld\n", res);  
  65.         else if(state==1)  
  66.             printf("My God\n");  
  67.     }  
  68.    
  69.     return 0;  
  70. }  
  71. /************************************************************** 
  72.     Problem: 1508 
  73.     User: muddytu 
  74.     Language: C 
  75.     Result: Accepted 
  76.     Time:0 ms 
  77.     Memory:912 kb 
  78. ****************************************************************/  
    无力吐槽了,稀里糊涂的搞了整整一个晚上,竟然是这样的结果。我还是觉得第一次的代码是最正确的,不应该将类似123abc这样的输入纳入合法的输入范围中。



猜你喜欢

转载自blog.csdn.net/zwt7790195/article/details/69389064
今日推荐