字符串面试题(一)字符串逆序
字符串逆序可以說是最經常考的題目。這是一道入門級的題目,相信80%的程序員經歷過這道題。給定一個字符串s,將s中的字符順序顛倒過來,比如s="abcd",逆序后變成s="dcba"。
普通逆序
基本上沒有這么考的,放在這里主要是為了和后面的原地逆序做個對比。很簡單,直接分配一個與原字符串等長的字符數組,然后反向拷貝一下即可。
char* Reverse(char* s) {//將q指向字符串最后一個字符char* q = s ;while( *q++ ) ;q -= 2 ; //分配空間,存儲逆序后的字符串。char* p = newchar[sizeof(char) * (q - s + 2)] ; char* r = p ;// 逆序存儲while(q >= s)*p++ = *q-- ;*p = '\0' ;return r ; }
原地逆序
英文叫做in-place reverse。這是最常考的,原地逆序意味著不允額外分配空間,主要有以下幾種方法,思想都差不多,就是將字符串兩邊的字符逐個交換,如下圖。給定字符串"abcdef",逆序的過程分別是交換字符a和f,交換字符b和e,交換字符c和d。
一 設置兩個指針,分別指向字符串的頭部和尾部,然后交換兩個指針所指的字符,并向中間移動指針直到交叉。
char* Reverse(char* s) {// p指向字符串頭部char* p = s ;// q指向字符串尾部char* q = s ;while( *q )++q ;q -- ;// 交換并移動指針,直到p和q交叉while(q > p){char t = *p ;*p++ = *q ;*q-- = t ;}return s ; }
二 用遞歸的方式,需要給定逆序的區間,調用方法:Reverse(s, 0, strlen(s)) ;
// 對字符串s在區間left和right之間進行逆序,遞歸法 void 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) ; }
三 非遞歸法,同樣指定逆序區間,和方法一沒有本質區別,一個使用指針,一個使用下標。
// 對字符串str在區間left和right之間進行逆序 char* Reverse( char* s, int left, int right ) {while( left < right ){char t = s[left] ;s[left++] = s[right] ;s[right--] = t ;}return s ; }
不允許臨時變量的原地逆序
使用異或操作
// 使用異或操作對字符串s進行逆序 char* Reverse(char* s) {char* r = s ;//令p指向字符串最后一個字符char* p = s;while (*(p + 1) != '\0')++p ;// 使用異或操作進行交換while (p > s){*p = *p ^ *s ;*s = *p ^ *s ;*p = *p-- ^ *s++ ;}return r ; }
按單詞逆序
給定一個字符串,按單詞將該字符串逆序,比如給定"This is a sentence",則輸出是"sentence a is This",為了簡化問題,字符串中不包含標點符號。
分兩步
1 先按單詞逆序得到"sihT si a ecnetnes"
2 再整個句子逆序得到"sentence a is This"
對于步驟一,關鍵是如何確定單詞,這里以空格為單詞的分界。當找到一個單詞后,就可以使用上面講過的方法將這個單詞進行逆序,當所有的單詞都逆序以后,將整個句子看做一個整體(即一個大的包含空格的單詞)再逆序一次即可,如下圖所示,第一行是原始字符換,第二行是按單詞逆序后的字符串,最后一行是按整個句子逆序后的字符串。
代碼
// 對指針p和q之間的所有字符逆序 void ReverseWord(char* p, char* q) {while(p < q){char t = *p ;*p++ = *q ;*q-- = t ;} }// 將句子按單詞逆序 char* ReverseSentence(char* s) {// 這兩個指針用來確定一個單詞的首尾邊界char* p = s ; // 指向單詞的首字符char* q = s ; // 指向空格或者 '\0'while(*q != '\0'){if (*q == ''){ReverseWord(p, q - 1) ;q++ ; // 指向下一個單詞首字符p = q ;}elseq++ ;}ReverseWord(p, q - 1) ; // 對最后一個單詞逆序ReverseWord(s, q - 1) ; // 對整個句子逆序return s ; }
逆序打印
還有一類題目是要求逆序輸出,而不要求真正的逆序存儲。這題很簡單,有下面幾種方法,有的方法效率不高,這里僅是提供一個思路而已。
先求出字符串長度,然后反向遍歷即可。
void?ReversePrint(const?char*?s){
? ? int?len?=?strlen(s) ;
? ? for?(int?i?=?len?-?1; i?>=?0;?--i)
? ? ? ? cout?<<?s[i];
}
如果不想求字符串的長度,可以先遍歷到末尾,然后在遍歷回來,這要借助字符串的結束符'\0
void ReversePrint(const char* s) {const char* p = s ;while (*p)*p++ ;--p ; //while結束時,p指向'\0',這里讓p指向最后一個字符while (p >= s){cout <<*p ;--p ;} }
對于上面第二種方法,也可以使用遞歸的方式完成。
void?ReversePrint(const?char*?s){
? ? if(*(s?+1)?!=?'\0')
? ? ? ? ReversePrint(s?+?1) ;
? ? cout?<<?*s ;
}
FROM:?http://www.cnblogs.com/graphics/archive/2011/03/09/1977717.html
總結
以上是生活随笔為你收集整理的字符串面试题(一)字符串逆序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鼋头渚什么时候关门
- 下一篇: 商业用电电费多少钱一度?