《剑指Offer》面试题:将字符串转换为整数

题目

题目:把字符串转化为整数 ,若输入无效,则返回0且将标志位设为true

自己以前在一些书上面看到过关于 字符串转化为整数的例子,心中有点印象,知道要考虑一些特殊情况。今天决定写下这段代码,发现代码写的稀烂,重复度太大,需要改善。

刚实现的代码如下:

/* 题目:把字符串转化为整数 ,若输入无效,则返回0且将标志位设为true; 需要考虑的测试用例如下: 1)"123" 2)"+123" //带符号的正数输入 3)"-123" 4) " abd123 " //非法输入 5) NULL */

#include<stdio.h>
#include<string.h>


/*功能:检查str中的字符是否全部是由数字构成 ,若是,则返回true,否则返回false @param str:字符串 @param begin:字符串的起始下标 @parameter end:字符串的 终止下标 */
bool checkStr(char *str,int begin,int end){
    if(begin<end){
        for(int i=begin;i<end;i++){
        if(!(str[i]>='0'&&str[i]<='9')){
            return false;
        }
        }
        return true; 
    }
    else{
        return false;
    }



}
/* 开始转换 */
int beginStringToNum(char *str,int begin,int end){
    int num=0;
    for(int i=begin;i<end;i++){
        num=num*10+str[i]-'0';
    }
    return num;
}
void strToNum(char *str){
    bool str_illege=false; 
    int num=0; 
    //先检查str是否有效
    if(str==NULL||str==""){
        str_illege=true;
        printf("%d %d\n",str_illege,num); 
        return;
    } 
    int len=strlen(str);
    bool flag=false;

    if(str[0]=='+'){
  //若第一个字符为"+"时
        flag=checkStr(str,1,len);
        if(flag){
            num=beginStringToNum(str,1,len);
        }
        else{
            str_illege=true;
        }
    }
    else if(str[0]=='-'){
  //若第一个字符是"-"时
        flag=checkStr(str,1,len);
        if(flag){
            num=beginStringToNum(str,1,len)*(-1);
        }
        else{
            str_illege=true;
            printf("%d %d\n",str_illege,num); 
            return;
        }

    }
    else{
  //第一个字符不是“=”和“-”的情况
        flag=checkStr(str,0,len);
        if(flag){
            num=beginStringToNum(str,0,len);
        }
        else{
            num=0;
            str_illege=true;
            printf("%d %d\n",str_illege,num); 
            return;
        }
    }

    printf("%d %d\n",str_illege,num); 

}

测试用例如下:

int main(void){
    char *str;
    //gets(str);
    //直接用测试用例来测试
    //正常情况下的3中不同的输入 
    char str1[]="123";
    char str2[]="-123";
    char str3[]="+123";
    //只输入一个"+" 或者是 "-"
    char str4[]="+" ;
    char str5[]="-";
    //不可以转换的输入
    char str6[]="abc123";
    char str7[]="";
    char *str8=NULL;
    strToNum(str1);
    strToNum(str2);
    strToNum(str3);
    strToNum(str4);
    strToNum(str5);
    strToNum(str6);
    strToNum(str7);
    strToNum(str8);
    return 0;
}

而看别人的博客(http://blog.sina.com.cn/s/blog_74a459380101ennz.html),发现真的写的挺好的,摘入如下

题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串”345”,则输出整数345。 分析:这道题尽管不是很难,学过C/C++语言一般都能实现基本功能,但不同程序员就这道题写出的代码有很大区别,可以说这道题能够很好地反应出程序员的思维和编程习惯,因此已经被包括微软在内的多家公司用作面试题。

转换的思路:每扫描到一个字符,我们把在之前得到的数字乘以10再加上当前字符表示的数字。这个思路用循环不难实现。
由于整数可能不仅仅只含有数字,还有可能以’+’或者’-‘开头,表示整数的正负。因此我们需要把这个字符串的第一个字符做特殊处理。如果第一个字符是’+’号,则不需要做任何操作;如果第一个字符是’-‘号,则表明这个整数是个负数,在最后的时候我们要把得到的数值变成负数。
接着我们试着处理非法输入。由于输入的是指针,在使用指针之前,我们要做的第一件是判断这个指针是不是为空。如果试着去访问空指针,将不可避免地导致程序崩溃。另外,输入的字符串中可能含有不是数字的字符。每当碰到这些非法的字符,我们就没有必要再继续转换。最后一个需要考虑的问题是溢出问题。由于输入的数字是以字符串的形式输入,因此有可能输入一个很大的数字转换之后会超过能够表示的最大的整数而溢出。

enum Status {kValid = 0, kInvalid};
int g_nStatus = kValid;
///////////////////////////////////////////////////////////////////////
// Convert a string into an integer
///////////////////////////////////////////////////////////////////////
int StrToInt(const char* str)
{
       g_nStatus = kInvalid;
      long long num = 0;
      if(str != NULL)//至少保证字符串不为空
       {
            const char* digit = str;//用了一下中间变量,保存原始字符串,防止被破坏
            // the first char in the string maybe '+' or '-'
            bool minus = false;
            if(*digit == '+')//通过第一个字符判断是正是负
                   digit ++;
            else if(*digit == '-')
             {
                   digit ++;
                   minus = true;
             }
            // the remaining chars in the string
            while(*digit != '\0')//字符串结束标志
             {
                  if(*digit >= '0' && *digit <= '9')
                   {
                         num = num * 10 + (*digit - '0');
                        // overflow 
                        if(num > std::numeric_limits::max())//整数溢出的情况
                         {
                               num = 0;
                               break;
                         }
                         digit ++;
                   }
                  // if the char is not a digit, invalid input
                  else
                   {
                         num = 0;
                        break;
                   }
             }
            if(*digit == '\0')
             {
                   g_nStatus = kValid;
                  if(minus)
                         num = 0 - num;//转化为负数的方式
             }
       }
       return static_cast(num);
}
    原文作者:HelloWorld_EE
    原文地址: https://blog.csdn.net/u010412719/article/details/48108533
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞