一個很簡潔的演算法:
void Reverse(char s[])
{
for(int i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
char c = s[i];
s[i] = s[j];
s[j] = c;
}
}
#關於a, b交換其它演算法:
a ^= b;
b ^= a;
a ^= b;
一個五種解法的版本:
轉自:http://www.cnblogs.com/Mainz/articles/1164602.html
這是網路流傳的Microsoft的面試題目之一:“編寫反轉字串的程式,要求最佳化速度、最佳化空間”。因為最近一直很多關注演算法方面的實踐和研究,因此對這個問題進行了一些思考,給出了5種實現方法(有兩種解法相關性比較大)。
解法一:第一次看到這題目,想到最簡單、最直覺的解法就是:遍曆字串,將第一個字元和最後一個交換,第二個和倒數第二個交換,依次迴圈,即可,於是有了第一個解法:
char* strrev1(const char* str)
{
int len = strlen(str);
char* tmp = new char[len + 1];
strcpy(tmp,str);
for (int i = 0; i < len/2; ++i)
{
char c = tmp[i];
tmp[i] = tmp[len – i - 1];
tmp[len – i - 1] = c;
}
return tmp;
}
這裡是通過數組的下標方式訪問字串的字元,實際上用指標直接操作即可。解法二正是基於此,實現代碼為:
char* strrev2(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
char t = *tmp;
*tmp = *p;
*p = t;
--p;
++tmp;
}
return ret;
}
顯然上面的兩個解法中沒有考慮時間和空間的最佳化,一個典型的最佳化策略就是兩個字元交換的演算法最佳化,我們可以完全不使用任何外部變數即完成兩個字元(或者整數)的交換,這也是一個很經典的面試題目。特別是一些嵌入式硬體相關編程中經常要考慮寄存器的使用,因此經常有不使用任何第三個寄存器即完成兩個寄存器資料的交換的題目。一般有兩個解法,對應這裡的解法三和解法四。
接上文
解法三的實現代碼為:
char* strrev3(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
*p ^= *tmp;
*tmp ^= *p;
*p ^= *tmp;
--p;
++tmp;
}
return ret;
}
解法四的實現代碼為:
char* strrev4(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
*p = *p + *tmp;
*tmp = *p - *tmp;
*p = *p - *tmp;
--p;
++tmp;
}
return ret;
}
實際上我們還可以通過遞迴的思想來解決這個問題,思想很簡單:每次交換首尾兩個字元,中間部分則又變為和原來字串同樣的問題,因此可以通過遞迴的思想來解決這個問題,對應解法五的實現代碼為:
char* strrev5(/**//*const */char* str,int len)
{
if (len <= 1)
return str;
char t = *str;
*str = *(str + len -1);
*(str + len -1) = t;
return (strrev5(str + 1,len - 2) - 1);
}
以下給出一個測試程式:
nt main(int argc,char* argv[])
{
char* str = "hello";
P(str);
char* str2 = strrev1(str);
P(str2);
char* str3 = strrev2(str2);
P(str3);
char* str4 = strrev3(str3);
P(str4);
char* str5 = strrev4(str4);
P(str5);
char* str6 = strrev5(str5,strlen(str5));
P(str6);
return 0;
}
你就可以看到字串"hello"和"olleh"交替輸出了。
說明:1)這裡解法中沒有認真考慮輸入字串的合法性和特殊長度(如NULL、一個字元等)字串的處理;2)前4個演算法不改變輸入字串的值,解法五修改了輸入字串。