字串倒序反轉程式
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//方法一:將第一個字元和最後一個互換,第二個和倒數第二個互換,如此依次迴圈下去
char *strrev1(const char *str)
{
int len = strlen(str);
char *tmp = (char*)malloc(len + 1);
strcpy(tmp,str);
int i = 0;
for (i = 0; i < len/2; ++i)
{
char c = tmp[i];
tmp[i] = tmp[len-i-1];
tmp[len-i-1] = c;
}
return tmp;
free(tmp);
}
//方法二:用指標實現
char *strrev2(const char *str)
{
char *tmp = (char*)malloc(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;
free(tmp);
}
//方法三:
char *strrev3(const char *str)
{
char *tmp = (char*)malloc(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;
free(tmp);
}
/*
顯然上面的兩個解法中沒有考慮時間和空間的優化,一個典型的優化策略就是兩個字元交換的演算法優化,我們可以完全不使用任何外部變數即完成兩個字元(或者整數)的交換,這也是一個很經典的面試題目。特別是一些嵌入式硬體相關程式設計中經常要考慮暫存器的使用,因此經常有不使用任何第三個暫存器即完成兩個暫存器資料的交換的題目。一般有兩個解法,對應這裡的解法三和解法四。*/
char *strrev4(const char *str)
{
char *tmp = (char*)malloc(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;
free(tmp);
}
/*還可以通過遞迴的思想來解決這個問題,思想很簡單:每次交換首尾兩個字元,中間部分則又變為和原來字元串同樣的問題,因此可以通過遞迴的思想來解決這個問題,對應解法五的實現程式碼為:*/
char *strrev5(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);
}
int main(int argc,char *argv[])
{
char *str = "ABCD1234efgh";
printf("%s/n",str);
char *str1 = strrev1(str);
printf("%s/n",str1);
char *str2 = strrev2(str1);
printf("%s/n",str2);
char *str3 = strrev3(str2);
printf("%s/n",str3);
char *str4 = strrev4(str3);
printf("%s/n",str4);
char *str5 = strrev5(str4,strlen(str));
printf("%s/n",str5);
return 0;
}
你就可以看到字串"ABCD1234efgh"和"hgfe4321DCBA"交替輸出了。
說明:1)這裡解法中沒有認真考慮輸入字串的合法性和特殊長度(如NULL、一個字元等)字串的處理;2)前4個演算法不改變輸入字串的值,解法五修改了輸入字串