面试字符串篇—字符串常考知识点汇总

字符串看似简单,却在面试中层出不穷。做出来关于字符串的题目简单,能够完全准确的写出来不容易。

究其原因,无非以下几点:

    1)边界情况处理

    2)异常情况处理  

    3)指针操作

在网易有道的二面过程中,面试官就曾经出过atoi以及itoa的实现这种题目,当时以最快且无bug的形式写出来,面试官很满意。因此对于相关字符串原型的实现,必须熟记于心,熟练于手。

下面我将总结常见字符串常考知识点:

1、atoi实现(字符串转换为整数)

2、itoa实现(整数转换为字符串)

3、strcmp实现(比较两个字符串大小)

4、strcpy实现(拷贝字符串到指定位置)

5、strlen实现(字符串长度)

6、strstr实现(寻找子串出现的位置)

7、memcpy实现(内存级的复制内容)

8、memmove实现(内存级的复制)

9、reverse实现(反转一个字符串)

10、reverse_sentence(反转一句话中的每一个单词)

下面将从源代码级别对各个题目进行讲解。

一、atoi实现(字符串转换为整数)

   atoi的原型为 int atoi(const char* str) 。实现atoi需要注意如下几点:

   1:输入指针的合法性 

   2:字符串前面可能包含空格

   3:字符串中可能包含正负号

   4:字符串可能包含非数字字符

   5:字符串转换为数字的规则

   6:转换后的整数有可能溢出

  上述6点都必须要注意到,面试官看你写的程序着重会看这6点,缺哪一个都会影响你的面试成绩。

//将字符串转换成整数
//作者:张海波
//时间:2013-12-9
int atoi(const char* str)
{
    //判断指针是否为NULL
    assert( str != NULL);
    //去除字符串前面的空格
    while(isspace(*str))
        ++str;
    //判断正负号
    int sign = 1;
    if(*str == '-')
        sign = -1;
    if(*str == '-' || *str == '+')
        ++str;
    //开始进行转换,直至第一个非数字的字符
    int result = 0;
    while(isdigit(*str))
    {
        result = result*10 + (*str-'0');
        //判断是否发生溢出
        if((result>>31)&0x1 == 1)
        {
            if(sign > 0)
                return INT_MAX;
            else
                return INT_MIN;
        }

        ++str;
    }

    //返回转换后的结果
    return result;
}

(二)itoa实现(整数转换为字符串)

itoa函数的原型为char* itoa(int value, char* str, int radix) 其中value是待转换的整数,str是转换后字符串的第一个字符,radix是转换进制。

itoa实现需要注意如下几点:

 1:判断指针是否为NULL

 2:判断输入的整数是否为0

 3:整数是否为负,且正负号转换为字符

 4:逆向转换规则

//整数转换为字符串
//作者:张海波
//时间:2013-12-9
char* itoa(int value, char* str, int radix)
{
    //判断指针是否为NULL
    assert( str != NULL);
    //判断value是否为0
    char* ret = str;
    if(value == 0)
    {
        *str = 0;
        ++str;
        *str = '\0';
        return ret;
    }
    //判断正负,如果为负,转换为正进行处理
    int sign = (value < 0 ? -1 : 1);
    int a, b;
    b = (sign < 0 ? (-1)*value : value);

    //开始逐位进行转换
    char* p = str;
    while( b != 0)
    {
        a = b % radix;
        b = b / radix;
        if(a < 10)
            *p = a + '0';
        else
            *p = a - 10 + 'A';
        ++p;
    }

    //将符号压入进去
    if(sign == -1)
        *p++ = '-';
    //反转字符串
    *p = '\0';
    --p;
    while(str < p)
    {
        *str = *p + *str;
        *p = *str - *p;
        *str  = *str - *p;
        ++str, --p;
    }

    return ret;
}

(三)strcmp实现(比较两个字符串的大小)

strcmp实现需要注意如下三点:

1、字符串合法性检查

2、源字符串和目标字符串是否指向同一个字符串

3、判断条件

//比较两个字符串的大小
//作者:张海波
//时间:2013-12-10
int strcmp(const char* src, const char* dst)
{
    //判断两个指针的合法性
    assert(src != NULL  && dst != NULL);
    //判断两个指针是否指向同一个字符串
    if(src == dst)
        return 0;
    //对每一个字符逐一进行判断
    int ret = 0;
    while(!(ret = *(unsigned char*)src - *(unsigned char*)dst) 
        && *src && *dst){
        ++src, ++dst;
    }
    //判断谁大谁小
    if(ret < 0)
        ret = -1;
    else if(ret > 0)
        ret = 1;

    return ret;
}

(四)strcpy实现(拷贝字符串)

strcpy的实现需要注意如下几点:

1、输入指针合法性检查

2、目标字符串和源字符串是否相同

3、复制规则

//拷贝指定的字符串
//作者:张海波
//时间:2013-12-10
char* strcpy(char* dest, const char* source)
{
    //判断两个指针的合法性
    assert(dest != NULL && source != NULL);
    //判断源字符串和目标字符串是否重合
    if(dest == source)
        return dest;
    //保存目标字符串首地址,并且一一进行复制
    char* ret = dest;
    while((*dest++ = *source++) != '\0');
    
    return ret;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值