轉載請註明出處: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這樣的輸入納入合法的輸入範圍中。