题目描述
对字符串中的所有单词进行倒排。
说明:
1、每个单词是以26个大写或小写英文字母构成;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
4、每个单词最长20个字母;
输入描述:
输入一行以空格来分隔的句子
输出描述:
输出句子的逆序
输入例子:
I am a student
输出例子:
student a am I
此题可以说是《句子逆序》一题的强化版,题目给出的例子非常简单,实际测试用例像这样:
$bo*yo gi!r# #
可以看到其中会出现连续多个分隔符的情况,并且输出时对应分隔符的位置只能保留一个空格。
因此此题相对于句子逆序一题升级为:
1.句子中间可能出现任意非英文字符,都应该是字符串的分隔符,句子逆序后分隔符替换为空格;
2.当出现多个分隔符时,只保留一个空格输出。
因此第一个任务便是实现一个以任意非英文字符分隔的split()函数,STL并没有类似的函数,此前自己写过两个split,总结一下:
//split版本1:指定sep作为分隔符,但一次调用只能指定一种分隔符
vector<string> split(string str, char sep){
stringstream stream(str);
string temp;
vector<string> res;
while(getline(stream, temp, sep)){
res.push_back(temp);
}
return res;
}
//split版本2:空格作为分隔符,可以修改代码改变分隔符
vector<string> split(string str)
{
vector<string> vec_str;
string temp;
auto it=str.begin();
while(*it){
auto iter=it;
for(;iter!=str.end();iter++)
{
if(isspace(*iter)){
it=iter+1;
break;
}
temp+=*iter;
}
vec_str.push_back(temp);
temp.clear();
if(iter==str.end())break;
}
return vec_str;
}
第一个split()采用stringstream实现,简洁而优雅,但是每次只能按一个分隔符分割,此题需要按照任意非英文字符分割,因此改写第二个split()版本:
//split版本3:按任意非英文字符分隔
vector<string> split(string str)
{
vector<string> vec_str;
string temp;
auto it=str.begin();
while(*it){
auto iter=it;
for(;iter!=str.end();iter++)
{
if((*iter<'A')||(*iter>'z')||(*iter>'Z'&&*iter<'a')){//非英文字符均作为分隔符
it=iter+1;
break;
}
temp+=*iter;
}
vec_str.push_back(temp);
temp.clear();
if(iter==str.end())break;
}
return vec_str;
}
工具准备好后,此题就简单了,第二个要解决的问题是按照上述split()分割后,vector<string>中会出现多余空格字符,应该全部删掉。
因此考虑使用remove()删除所有的"",但是注意:remove() 并不是真正删除元素,而是将删除的元素移到容器末尾并返回第一个元素的迭代器,根据该迭代器和end()即可真正删除元素。因此remove()函数的正确使用方法如下:
//删除所有多余空格字符
auto iter=remove(vec_str.begin(),vec_str.end(),"");//remove把所有""移到末尾并返回第一个iterator
vec_str.erase(iter,vec_str.end());//然后删除所有空格
此时得到的vec_str已经非常“干净”了。。只需要调用reverse()函数逆序一下,再按要求输出就行了。
此题完整AC过的代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
//split版本2:任意非英文字符分隔
vector<string> split(string str)
{
vector<string> vec_str;
string temp;
auto it=str.begin();
while(*it){
auto iter=it;
for(;iter!=str.end();iter++)
{
if((*iter<'A')||(*iter>'z')||(*iter>'Z'&&*iter<'a')){
it=iter+1;
break;
}
temp+=*iter;
}
vec_str.push_back(temp);
temp.clear();
if(iter==str.end())break;
}
return vec_str;
}
int main()
{
string str;
while(getline(cin,str)){
vector<string> vec_str=split(str);
//删除所有多余空格字符
auto iter=remove(vec_str.begin(),vec_str.end(),"");//remove把所有''移到末尾并返回第一个iterator
vec_str.erase(iter,vec_str.end());//然后删除所有空格
reverse(vec_str.begin(),vec_str.end());
auto it=vec_str.begin();
for(;it!=vec_str.end()-1;it++){
cout<<*it<<' ';
}
cout<<*it<<endl;
}
return 0;
}