代码改变世界

面试题2:实现字符串逆序

2016-03-21 20:35  Keiven_LY  阅读(3014)  评论(0编辑  收藏  举报

题目描述

给定一个字符串s,将s中的字符顺序颠倒过来,比如s="abcd",逆序后变成s="dcba"。

方法一:普通逆序

基本思想:直接分配一个与原字符串等长的字符数组,然后反向拷贝一下即可

char *reverse(char *s)
{
    char *q=s;
    while(*q++)
        ;    
    q-=2;   //将指针q指向字符串的最后一个字符
    char *p = new char[sizeof(char) * (q - s + 2)] ; //分配空间,存储逆序后的字符串。
    char *r=p;  //用于返回逆序后的字符串
    while(q > s)
        *p++ = *q--;;
    *p = '\0';
    return r;    
}

方法二:原地逆序

基本思想:原地逆序意味着不允额外分配空间,就是将字符串两边的字符逐个交换。如给定字符串"abcdef",逆序的过程分别是交换字符a和f,交换字符b和e,交换字符c和d。设置两个指针,分别指向字符串的头部和尾部,然后交换两个指针所指的字符,并向中间移动指针直到交叉。

char *reverse2(char *s)
{
    char *p = s;//指针p指向s的头
    char *q = s;
    while(*q)
        q++;
    q--;        //指针q指向s的尾
    while(q > p)
    {
        char t = *p;
        *p = *q;
        *q =t;
        p++;
        q--;
    }
    return s;
}

方法三:递归

基本思想:在给定区间内,对字符串逆序处理,递归调用方法:Reverse(s, 0, strlen(s)) ;

char *reverse(char *s, int left, int right)
{
    if(left > right)
        return s;
    char t = s[left];
    s[left] = s[right];
    s[right] = t;
    reverse(s,left+1,right-1);
}

方法四:不允许使用临时变量的原地逆序

基本思想:不使用临时变量,也就是要修改交换部分。一是异或操作,因为异或操作可以交换两个变量而无需借助第三个变量,二是使用字符串的结束符'\0'所在的位置作为交换空间,这样有个局限,就是只适合以'\0'结尾的字符串,对于不支持这种字符串格式的语言,就不能使用了。

//使用字符串结束符'\0'所在的位置作为交换空间:
char *reverse(char *s)
{
    char *r = s;//作为返回指针
    char *p = s;
    while(*p != '\0')
        ++p;           //使指针p指向结束符'\0'
    char *q = p-1;  //使指针q指向字符串的最后一个字符
    
    // 使用p作为交换空间逐个交换字符
    while (q > s)
    {
        *p = *q ;
        *q-- = *s ;
        *s++ = *p ;
    }
    *p = '\0' ; // 恢复结束符
    return r;    
}
//使用异或操作
char *reverse(char *s)
{
    char *r = s;//作为返回指针
    char *p = s;
    while(*p)
        ++p;
    p--;         //使指针p指向字符串的最后一个字符
    while(p > s)
    {
        *p = *p ^ *s;
        *s = *p ^ *s;
        *p = *p ^ *s;
        p--;
        s++;
    }
    return r;
}