将一篇文章的按单词倒序,将一个字符串向左循环移动

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值