【劍指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的程式碼,拿來測試了下,結果各種非法的輸入都沒處理,很多非法的輸入,得到的都是些五花八門的答案。
先貼上程式碼,大家幫我看下有木有沒考慮到的地方:
#include<stdio.h>
#include<stdbool.h>
bool IsValid;
long StrToIInt(const char *str)
{
//非法輸入
if(str == NULL)
{
IsValid = false;
return 0;
}
//是否為負數
bool IsMinus = false;
//跳過前面的空白字元
while(*str == ' ')
str++;
//第一個非空白字元為+號
if(*str == '+')
str++;
//第一個非空白字元為-號
else if(*str == '-')
{
str++;
IsMinus = true;
}
//如果只輸入了空白字元、符號位,或者什麼都沒輸入,也為非法輸入
if(*str == '\0')
{
IsValid = false;
return 0;
}
//後面的輸入如果合法,則轉化為整數
long num = 0; //轉化為整數後的結果
//這樣可以使類似234asd的輸入也判定為合法輸入,得到的結果為234
while(*str != '\0')
{
//輸入不在0-9之間,屬於非法輸入
if(*str<'0' || *str>'9')
{
IsValid = false;
return 0;
}
//對不包含符號位的合法輸入進行轉換
num = 10*num + (*str - '0');
str++;
}
//根據符號位轉換正負
num = IsMinus ? (-1*num) : num;
//判斷是否溢位了int的範圍
if(num>0X7FFFFFFF || num<(signed int)0X80000000)
{
IsValid = false;
return 0;
}
//上面沒有返回,則說明合法並沒有發生溢位
return num;
}
int main()
{
static char str[100000000];
while(gets(str) != NULL)
{
IsValid = true;
long result = StrToIInt(str);
if(IsValid)
printf("%ld\n",result);
else
printf("My God\n");
}
return 0;
}
最後查到有些人講類似123abc這樣的輸入也作為合法輸入,這樣得到的結果是123,去掉了後面的非法字元,我就索性又把程式改了下,把這種情況納入合法輸入的範圍內,改成如下程式碼:
#include<stdio.h>
#include<stdbool.h>
bool IsValid;
long StrToIInt(const char *str)
{
//非法輸入
if(str == NULL)
{
IsValid = false;
return 0;
}
//是否為負數
bool IsMinus = false;
//跳過前面的空白字元
while(*str == ' ')
str++;
//第一個非空白字元為+號
if(*str == '+')
str++;
//第一個非空白字元為-號
else if(*str == '-')
{
str++;
IsMinus = true;
}
//如果只輸入了空白字元、符號位,或者什麼都沒輸入,也為非法輸入
// if(*str == '\0')
// {
// IsValid = false;
// return 0;
// }
//如果第一個非負號位輸入的不是0-9的數字,為非法輸入
if(*str<'0' || *str>'9')
{
IsValid = false;
return 0;
}
//後面的輸入如果合法,則轉化為整數
long num = 0; //轉化為整數後的結果
//這樣可以使類似234asd的輸入也判定為合法輸入,得到的結果為234
while(*str != '\0' && *str>='0' && *str<='9')
{
//輸入不在0-9之間,屬於非法輸入
// if(*str<'0' || *str>'9')
// {
// IsValid = false;
// return 0;
// }
//對不包含符號位的合法輸入進行轉換
num = 10*num + (*str - '0');
str++;
}
//根據符號位轉換正負
num = IsMinus ? (-1*num) : num;
//判斷是否溢位了int的範圍
if(num>0X7FFFFFFF || num<(signed int)0X80000000)
{
IsValid = false;
return 0;
}
//上面沒有返回,則說明合法並沒有發生溢位
return num;
}
int main()
{
static char str[100000000];
while(gets(str) != NULL)
{
IsValid = true;
long result = StrToIInt(str);
if(IsValid)
printf("%ld\n",result);
else
printf("My God\n");
}
return 0;
}
這次居然前三個測試用例通過了,後面兩個WA了,搞得我暈頭轉向,下載了個別人的AC程式碼,一眼看過去就感覺很多非法輸入沒有考慮到,測試了下,確實很多非法的輸入,得到的結果五花八門。貼出來大家瞅瞅,分析下看是不是這道題的後臺測試用例有問題。別人AC的程式碼:
#include<stdio.h>
#include<stdlib.h>
int state=0;
long StrToInt(const char * str)
{
long num;
num = 0;
if(str!=NULL)
{
const char * digit = str;
int minus = 0; //判斷正負(第一個字元)
if(*digit=='+')
{
digit++;
}
else if(*digit=='-')
{
minus = 1;
digit++;
}
while(*digit!='\0') //'\0'與'0'區別
{
if(*digit>='0' && *digit<='9')
num = 10*num+(*digit-'0');
else
{
state=1;
num=0;
break;
} //輸入不合法
digit++;
state=0;
}
if(minus)
{
num = 0 - num;
}
}
return num;
}
int main()
{
long res;
char st[100];
char *p = st;
while(scanf("%s", p)!=EOF)
{
res = StrToInt(p);
if(state==0)
printf("%ld\n", res);
else if(state==1)
printf("My God\n");
}
return 0;
}
/**************************************************************
Problem: 1508
User: muddytu
Language: C
Result: Accepted
Time:0 ms
Memory:912 kb
****************************************************************/
無力吐槽了,稀裡糊塗的搞了整整一個晚上,竟然是這樣的結果。我還是覺得第一次的程式碼是最正確的,不應該將類似123abc這樣的輸入納入合法的輸入範圍中。相關文章
- 《劍指offer》:[49]把字串轉化成整數字串
- 劍指offer(Java版)--將字串轉換為整數Java字串
- 劍指offer——把字串轉換成整數C++字串C++
- 力扣 - 劍指 Offer 67. 把字串轉換成整數力扣字串
- 【劍指offer】左旋轉字串字串
- 《Leetcode of December》劍指 Offer 67. 把字串轉換成整數LeetCode字串
- 劍指Offer 表示數值的字串字串
- 《劍指offer》:[54]表示數值的字串字串
- 《劍指offer》:[42-1]左旋轉字串字串
- 【劍指offer】字串的排列字串
- 劍指Offer系列之「表示數值的字串」字串
- 劍指offer面試題11 數值的整數次方面試題
- 【劍指offer】【2】字串的空格字串
- 【劍指offer】字串的組合字串
- 劍指 Offer 38. 字串的排列字串
- 【leetcode】劍指 Offer 16. 數值的整數次方LeetCode
- 【劍指offer】調整陣列順序陣列
- 劍指offer-字串空格替換為“ ”字串
- 【劍指offer】替換字串中的空格字串
- 劍指offer:旋轉陣列的最小數字陣列
- 劍指offer 旋轉陣列的最小數字陣列
- 劍指offer—58_2.左旋轉字串—分析及程式碼(Java)字串Java
- 劍指offer-轉陣列的最小數字-php陣列PHP
- 【劍指Offer】調整陣列順序使奇數位於偶數前面陣列
- 【劍指offer】7.旋轉陣列的最小數字陣列
- 劍指 Offer 11. 旋轉陣列的最小數字陣列
- 【劍指 Offer】11. 旋轉陣列的最小數字陣列
- [劍指offer][第四章][28]字串的排列字串
- 劍指 Offer 21. 調整陣列順序使奇數位於偶數前面陣列
- LeetCode|劍指 Offer 49.醜數LeetCode
- 【劍指offer】把陣列排成最小的數陣列
- 劍指offer面試16 反轉連結串列面試
- 劍指offer-JavaScript版JavaScript
- 劍指Offer題解合集
- 劍指offer面試題14 調整陣列順序使奇數位於偶數前面面試題陣列
- 【Algorithm】《劍指offer》面試題32----從1到n整數中1出現的次數Go面試題
- 【劍指offer】旋轉陣列的最小值陣列
- 劍指 Offer 48. 最長不含重複字元的子字串字元字串