您的位置:首页 > 其它

ZOJ 1151 Word Reversal

2014-02-24 15:01 309 查看
题目链接: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,‘,’);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: