ZOJ 1151 Word Reversal

本文介绍了一种使用C++ STL处理字符串的方法,以解决ZJU ACM 151题中单词反转的问题。通过两种不同的实现方式,展示了如何利用istringstream和find_first_of函数来拆分和反转字符串中的单词。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=151

Hint:此题是将一行中的单词一个个反转过来,但单词的位置不变。看起来比较简单,但是由于存在多个数据块,程序控制上比较难。

         这里采用STL拆分字符串,将字符串按照空格拆分并提取出来,然后反转输出。

         主要思路如下:

         (1) 在搜索每一个符合条件的子串之前,先使子串起始位置等于子串结束位置(空格处)加1,然后按照find_first_of 函数查找相应子串,若有,则子串结束位置不等于                     起始位置,在利用substr函数取之间的字符,即得子串值。

          (2)上面的条件判断结束以后,下面的if语句是判断最后一个子串的边界条件的,若起始位置等于该字符串的长度,表明已无字符串可取,否则还有一个子串。

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<map>
#include<iterator>
#include<algorithm>
#include<numeric>
#include<cmath>
using namespace std;
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\\in.txt", "r", stdin);
        freopen("D:\\out.txt", "w", stdout);
    #endif // ONLINE_JUDEG
        int num(0);
        cin >> num;
        int n(0);
        string str;
        string ss;
        string strSeparator = " ";
        vector<string> coll;
        string strResult;//拆分结果串
        int size_pos = 0;//拆分子串结束位置
        int size_prev_pos = 0;//拆分子串起始位置
        int block = 1;
        for (int i = 0; i < num; i++)
        {
            if (i != 0)
            {
                cout << endl;
            }
            cin >> n;
            getchar();
            for (int j = 0; j < n; j++)
            {
                str = "";
                getline(cin, str);
                int flag = 1;//如果是第行中的第一个单词,输出格式不同
                size_pos = 0;
                size_prev_pos = 0;
                while ((size_pos = str.find_first_of(strSeparator, size_pos)) 
                    != string::npos)//找到子串
                {
                    //取子串
                    strResult = str.substr(size_prev_pos, size_pos - size_prev_pos);
                    reverse(strResult.begin(), strResult.end());//反转子串
                    if (1 == flag)
                    {
                        cout << strResult;
                    }
                    else
                    {
                        cout << " " << strResult;
                    }
                    flag = 0;
                    size_prev_pos = ++size_pos;//下一子串起始位置、结束位置=当前子串结束位置加1
                }
                if (size_prev_pos != str.size())//判断有无最后一个子串
                {
                    strResult = str.substr(size_prev_pos, size_pos - size_prev_pos);
                    reverse(strResult.begin(), strResult.end());
                    cout << " " << strResult<<endl;
                }
            }
        }
        return 0;
}

本题的另外一种更C++化的如下所示:

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<map>
#include<iterator>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<sstream>
using namespace std;
int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\\in.txt", "r", stdin);
        freopen("D:\\out.txt", "w", stdout);
    #endif // ONLINE_JUDEG
        int num(0);
        cin >> num;
        int n(0);
        string str;
        string ss;
        string strSeparator = " ";
        vector<string> coll;
        string strResult;//拆分结果串
        int size_pos = 0;//拆分子串结束位置
        int size_prev_pos = 0;//拆分子串起始位置
        int block = 1;
        for (int i = 0; i < num; i++)
        {
            if (i != 0)
            {
                cout << endl;
            }
            cin >> n;
            getchar();

            for (int j = 0; j < n; j++)
            {
                str = "";
                getline(cin, str);
                int flag = 1;//如果是第行中的第一个单词,输出格式不同
                istringstream istr(str);
                while (!istr.eof())
                {
                    istr >> strResult;
                    reverse(strResult.begin(), strResult.end());
                    if (1 == flag)
                    {
                        cout << strResult;
                        flag = 0;
                    }
                    else
                    {
                        cout << " " << strResult;
                    }
                }
                cout << endl;
            }
        }
        return 0;
}

这种解法巧妙把静态字符串进一步封装成istringstream对象,变为动态,再通过提取符符动态拆分字符串,这种“静态--动态”思维值得借鉴。但是可能又有一个问题:这种方法只能按空格拆分,若按其他字符比如“,”拆分,该如何处理呢?其实,只要用getline函数代替提取符“>>”就可以了,因为这个函数最后一个参数可以设置拆分字符,如下所示:

getline(istr,strResult,‘,’);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值