題目描述
給定一個字符串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; }