据说一道微软的面试题,要求考虑时间和空间的优化,下面给出几种通常字符串反转的方法:
1 直接数组操作
char
*
strReverse (
char
*
str )
{
int n = strlen ( str );
for ( int i = 0 ; i < n / 2 ; i ++ )
{
char temp = str[ i ] ;
str[i] = str[n - i - 1 ];
str[n - i - 1 ] = temp ;
}
return str ;
}
{
int n = strlen ( str );
for ( int i = 0 ; i < n / 2 ; i ++ )
{
char temp = str[ i ] ;
str[i] = str[n - i - 1 ];
str[n - i - 1 ] = temp ;
}
return str ;
}
这种做法原来的str没有保存,原来的str也改变了
2 指针操作
char
*
strReverse (
char
*
str )
{
char * p = str ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
char temp = * p ;
* p = * q;
* q = temp ;
}
return str ;
}
{
char * p = str ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
char temp = * p ;
* p = * q;
* q = temp ;
}
return str ;
}
上面俩中解法显然没有时间和空间的优化,记得上水木的时候看到反转俩个数的方法,没有引入任何的中间变量而且交换为为操作,速度更加的快,下面给出没有引入中间变量的交换俩个数的方法
3 通过位异或运算交换俩个数
char
*
strReverse (
char
*
str )
{
char * p = str + 0 ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
* p ^= * q ;
* q ^= * p ;
* p ^= * q ;
}
return str ;
}
{
char * p = str + 0 ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
* p ^= * q ;
* q ^= * p ;
* p ^= * q ;
}
return str ;
}
4 加减运算
char
*
strReverse (
char
*
str )
{
char * p = str + 0 ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
* p += * q ;
* q -= * p ;
* p -= * q ;
}
return str ;
}
{
char * p = str + 0 ;
char * q = str + strlen ( str ) - 1 ;
for ( ; p < q ; p ++ ,q -- )
{
* p += * q ;
* q -= * p ;
* p -= * q ;
}
return str ;
}
但是这种方法有个致命的限制,就是char为一个字节,表示的范围-128 - 127,*p += *q ;这个操作可能会引起益处的问题
上面俩种方法不仅没有用到中间变量,而且位运算的速度有所提高, 达到一定程度的时间和空间优化
上次上csdn的时候也碰到这个题目,不过是按照函数原形 char * strReverse ( const char * str ) 写个函数,递归的实现字符的反转,下面也给出实现的几种方法
1
,
char
*
strReverse (
char
*
str )
{
if ( * str == '
{
if ( * str == '
这种方法的效率很低,主要是每次递归都用strlen求字符的长度,strlen函数是相当耗时间的函数,而且引入了中间变量,这个方法不不可取的