【劍指offer】字串轉整數

蘭亭風雨發表於2014-06-02

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



相關文章