【剑指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】字符串转整数,布布扣,bubuko.com

时间: 2024-10-08 10:22:55

【剑指offer】字符串转整数的相关文章

剑指offer—字符串转换整数

对于这个问题, 本题考查的实际上就是字符串转换成整数的问题,或者说是要你自行实现atoi函数.那如何实现把表示整数的字符串正确地转换成整数呢?以"345"作为例子: 当我们扫描到字符串的第一个字符'3'时,由于我们知道这是第一位,所以得到数字3. 当扫描到第二个数字'4'时,而之前我们知道前面有一个3,所以便在后面加上一个数字4,那前面的3相当于30,因此得到数字:3*10+4=34. 继续扫描到字符'5','5'的前面已经有了34,由于前面的34相当于340,加上后面扫描到的5,最终

剑指offer之关于整数的处理

首先是整数次方的处理 在这处理的时候有几个细节主义处理 1.当指数是负数的时候 2.当指数式0的时候 3.当不满足条件的时候要抛出异常 再一个就是常用的将一个树化为二进制的形式,或者是求整数的幂或者矩阵 的幂 这个函数写的时候是用递归来写的,所以要注意跳出来的条件,第二使用递归来实现,三,用&操作代替原来的求%的操作,而且在用之前都要考虑这个范围的问题,一般会说参数为n,可是这个n到底是多大呢,用相应的类型去求解相应规模的运算 ----------------------------------

剑指offer之【整数中1出现的次数(从1到n整数中1出现的次数)】

题目: 整数中1出现的次数(从1到n整数中1出现的次数) 链接: https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述: 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此

[剑指offer] 字符串的顺序全排列

题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 结果请按字母顺序输出. 输入描述 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母. 输出描述 顺序输出字符串的所有排列 题目分析 这是一个字符串全排列的问题,把全部序列存在TreeSet中默认可得到字典顺序. TreeSet 基于TreeMap实现的SortedSet,可以对Set集合中的元

[剑指offer] 浮点数的整数次方

题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 输入描述 base,exponent 输出描述 base的exponent次方 题目分析 首先要注意,指数正负和零的情况判别: ①任何数的0次方等于0 ②0不能做除数(也就是指数为负时,基数不能为0) 解法一 运行时间:27ms 占用内存:636k public class Solution { public double Power(double base, int exp

剑指offer——数值的整数次方

题目:给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 下面来看代码: public class PowerSolution { public static double Power(double base, int exponent) { //当底数为0,指数小于0,则为非法情况. if (equal(base,0.0)&&exponent<0) { return 0.0f; } //当指数小于0的时候即求该数的倒数再乘

170319 剑指offer 1.把一个字符串转化成整数(简单问题的全面性考虑)

工作的时间越长,越感觉基础的重要性,当我们对程序的框架结构越来越熟悉的时候,越会注意这一点,在工作当中,功能的实现是重要的,但是代码的健壮性,重用性,与扩展性确往往更为重要,在学习新技术的同时,我们或许应该抽出一点时间,去思考代码可能出现的问题. 关于剑指offer的这本书,可能所有刚毕业找工作的人,或者准备找工作的人都曾经看过,但是当时我们面对一些东西的时候心情过于浮躁,往往忽视了简单的却又十分重要的环节,(ps:也可能只有我是这样) 面试中一道简单的问题(把一个字符串转化成整数) 可能接触c

剑指offer之【表示数值的字符串】

题目: 表示数值的字符串 链接: https://www.nowcoder.com/practice/6f8c901d091949a5837e24bb82a731f2?tpId=13&tqId=11206&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100",&quo

【剑指offer】字符串的排列

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26390551 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入: 每个测试案例包括1行. 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母. 输出: 对应每组数据,按字典序输出所有排列. 样例输入: abc BCA 样例输出: