华为机试在线训练-牛客网(19)【中级】单词倒排

题目描述

对字符串中的所有单词进行倒排。

说明:

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






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ctrlturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值