1.普通逆序
可以任意申请内存或变量,对于指针版本,此方法不好,需要在函数内开辟空间,在函数结束前返回该空间首地址,由于不能释放该内存,出现内存泄漏 ,所以这里只提供引用版本:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; void Reverse(string &str) { int len = str.size(); int i, j; char tmp; for (i = 0, j = len - 1; i < j; i++, j--) { tmp = str[i]; str[i] = str[j]; str[j] = tmp; } } int main(void) { string tmp; cin >> tmp; Reverse(tmp); cout << tmp << endl; return 0; }
2.字符串原地逆序
即不能开辟额外的内存空间,思想是将字符串两边的字符逐个交换位置。定义两个指针分别指向字符串头部和尾部。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; char* Reverse(char *str) { char* p = str; // p指针指向字符串头部 char* q = str; while (*q != ‘\0‘) q++; q--; //q指针指向字符串尾部 while (p < q) { char temp; temp = *p; *p++ = *q; *q-- = temp; } return str; } int main() { char str[50]; printf("请输入一个小于50的字符串:\n"); gets(str); cout<< endl << "原地逆序结果为:" << Reverse(str) << endl; return 0; }
3.字符串原地逆序-异或版
在要求不使用临时变量情况下可以使用异或交换两个变量的值。 先唠唠异或操作:
参与异或运算的两个变量,如果两个相应bit位相同,则结果为0,否则为1。
即:
0^0 = 0, 1^0 = 1, 0^1 = 1, 1^1 = 0
不难得出按位异或的几个特点:
(1) 任何数与全0异或,不变
(2) 任何数与全1异或, 取反
(3) 任何数与自己异或,则把自己置0
类似于不用中间变量交换两个变量的值:a = a + b; b = a – b; a = a – b;
不用中间变量交换两个变量的值还可以使用异或操作:
例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
a = a^b; //a=10100111
b = b^a; //b=10100001
a = a^b; //a=00000110
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; char* Reverse(char* str) { char* p = str; char* q = str; while (*q != ‘\0‘) q++; q--; while (p < q) { *p = *p ^ *q; *q = *p ^ *q; *p = *p ^ *q; p++; q--; } return str; } int main() { char str[50]; printf("请输入一个小于50的字符串:\n"); gets(str); cout<< endl << "原地逆序结果为:" << Reverse(str) << endl; return 0; }
4.对一个句子按单词逆序
比如,输入”I am a student”,要求输出”student a am I”
参考字符串原地逆序,不妨先将句子的输出结果逆序,即为”I ma a tneduts”,可以看出正好是输入句子中的每个单词的逆序。 则解题思路可以先将输入的句子按单词逆序,最后将结果再次逆序即可。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; void ReverseWord(char* p, char* q) { while (p < q) { char temp; temp = *p; *p++ = *q; *q-- = temp; } } char* ReverseSentence(char* str) { char* p = str; char* q = str; /* 处理整个句子内的单词 */ while (*q != ‘\0‘) { if (*q == ‘ ‘) /* 遇到空格:标志着单词结束*/ { ReverseWord(p, q-1); p = ++q; /* 指向下一个单词首字母 */ } else { q ++; } } /** 对最后一个单词逆序 **/ ReverseWord(p, q-1); /** 最后将整个句子逆序 **/ ReverseWord(str, q-1); return str; } int main() { char str[50]; printf("请输入一个小于50的字符串:\n"); gets(str); cout<< endl << "原地逆序结果为:" << ReverseSentence(str) << endl; return 0; }
5.字符串逆序打印
此类问题因为不需要存储,比较简单,这里只介绍一个利用递归的调用和回溯正好相反的小技巧。
比如:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //利用递归调用顺序和回溯顺序相反 void PrintString() { char char1; scanf("%c", &char1); if (char1 != ‘#‘) { PrintString(); } if(char1 != ‘#‘) { printf("%c", char1); } } int main() { PrintString(); return 0; }
更多阅读参考:http://www.cnblogs.com/graphics/archive/2011/03/09/1977717.html