#include <iostream>
// #include <algorithm> // 不想自己实现 reverse 函数,可以使用这个头文件
#include <stdio.h>
#include <string.h>
using namespace std;
char* reverse(char *beg , char *end); // 反转函数 ,参数为[beg, end]区间
char* left_move(char* str , int num); // 左移字符
char* right_move(char* str , int num); // 右移字符
char* reverse_text(char *beg , char *end); // 反转文章
int main()
{
char str[] = "123456789ABCDEF";
char* ps = left_move(str , 5);
cout << ps << endl;
ps = right_move(str , 5);
cout << ps << endl;
cout << reverse(str , str + strlen(str)) << endl; // 测试 自己实现的 reverse
char text[] = "| GNU LESSER GENERAL PUBLIC LICENSE\n"
"| Version 3, 29 June 2007\n\n\n"
"| Copyright (C) 2007 Free Software Foundation, Inc.\n"
"| ~~~ !!! @@@ ### $$ %%% ^^^ &&& *** ((( )))\n\n";
cout << text << endl;
cout << reverse_text(text , text + strlen(text)) << endl;
return 0;
}
char* left_move(char* str , int num) // 左移字符
{
reverse(str, str + num);
reverse(str + num , str + strlen(str));
reverse(str, str + strlen(str));
return str;
}
char* right_move(char* str , int num) // 右移字符
{
reverse(str, str + strlen(str));
reverse(str, str + num);
reverse(str + num , str + strlen(str));
return str;
}
char * reverse(char *beg , char *end) // 反转函数 ,参数为[beg, end]区间
{
char * ret = beg;
char temp;
end--; // 参数end,为结束标记,所以回退一格到真实结尾
while (end > beg) {
temp = *beg;
*beg = *end;
*end = temp;
beg++ , end--;
}
return ret;
}
char* reverse_text(char *beg , char *end) // 反转文章
{
char * ret = beg;
char * buf_text = new char[end - beg+1]; // 缓冲
reverse(beg , end); // 首先所有字符逆序
strcpy(buf_text , ret); // strtok会把找到的空格填\0而破环数据,所以buf一份求偏移
char *pos = NULL;
char *text = NULL;
pos = strtok(buf_text, " \t\n"); // 找空格
text = beg + (pos - buf_text); // text 为pos的映射
while (pos != NULL) {
reverse(text , text + strlen(pos));
pos = strtok(NULL, " \t\n"); // 找空格
text = beg + (pos - buf_text);
}
delete[] buf_text;
return ret;
}
#if(0) // 资料保护区
2、 用线性时间和常数附加空间将一篇文章的单词(不是字符)倒序。
/*答案:先将整篇文章的所有字符逆序(从两头起不断交换位置相对称的字符);
然后用同样的办法将每个单词内部的字符逆序。
这样,整篇文章的单词顺序颠倒了,但单词本身又被转回来了。*/
3、 用线性时间和常数附加空间将一个长度为n的字符串向左循环移动m位(例如,123456789 移动3位就变成了 456789123 )。
/*答案:把字符串切成长为m和n-m的两半。将这两个部分分别逆序,再对整个字符串逆序。*/
#endif
//思想是先逐个反转单词,然后反转上一步得到的整个字符串
#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
void Treverse(string &str)
{
string::iterator iter,word_iter;
iter = str.begin();
word_iter = iter;
while(*iter) {
if(!isspace(*iter) && isspace(*(iter+1))) { // 如果是单词结尾
reverse(word_iter, iter+1); // 反转单词
}
if(isspace(*iter) && !isspace(*(iter+1))) { // 如果是单词开始
word_iter = iter+1; // 设定单词开始标记
}
iter++;
}
// 但是最后一个单词以\0结束要单独处理
reverse(word_iter, iter);
//反转整个字符串
reverse(str.begin(),str.end());
}
int main()
{
string str("| GNU LESSER GENERAL PUBLIC LICENSE\n"
"| Version 3, 29 June 2007\n\n\n"
"| Copyright (C) 2007 Free Software Foundation, Inc.\n"
"| ~~~ !!! @@@ ### $$ %%% ^^^ &&& *** ((( )))\n\n");
cout <<"原来的字符串:\n" <<str << endl;
Treverse(str);
cout <<"反转后字符串:\n" << str << endl;
return 0;
}