代码改变世界

c++ STL unique

2012-06-29 13:46  youxin  阅读(791)  评论(0编辑  收藏  举报

  unique用来去掉重复的元素。函数原型如下:

template <class ForwardIterator>
  ForwardIterator unique ( ForwardIterator first, ForwardIterator last );

template <class ForwardIterator, class BinaryPredicate>
  ForwardIterator unique ( ForwardIterator first, ForwardIterator last,
                           BinaryPredicate pred );

Remove consecutive duplicates in range

Removes the duplicate consecutive elements from the range [first,last). This is done by removing all the elements that compare equal to the element right preceding them (only the first element in each group of consecutive equal elements is kept).

Return value

A forward iterator pointing to the new end of the sequence, which now does not include the elements that were consecutive duplicates.

指向新序列的末尾。

 题目:给定字符串,要求原地把相邻的多个空格替换为一个。如输入a_ _ b,输出:a_b

这道题不难,手写的话是单重循环,复杂度是O(N)时间和O(1)空间。这里展示用std::unique的解法。

unique是去除相邻的重复元素,我们只要把“重复元素”定义为“两个元素都是空格”即可。

struct AreBothSpaces
{
  bool operator()(char x, char y) const
  {
    return x == ' ' && y == ' ';
  }
};

void removeContinuousSpaces(std::string& str)
{
  std::string::iterator last
    = std::unique(str.begin(), str.end(), AreBothSpaces());
  str.erase(last, str.end());
}

 

注意移去等于前面值的元素,仅仅在连续的相等的元素中只有一个保留。

在一个序列想要移去多个重复的元素仅保留一个,一般要先排序再使用此函数

编程:一组单词,找出单词字母数>=6的单词数目,仅仅把相同的单词只计算一次。单词按照字母数目升序排列。

分析:

假定我们存储单词在vector<string>中,解决这个我们,我们要:

1.eliminate duplicate copies of each word

2. order the words based on size

3. count the words whose size is 6 or greater

想要实现1功能,如下:

sort(words.begin(),words.end());

vector<string>::iterator end_unique=unique(words.begin(),words.end());

words.erase(end_unique,words.end());

sort unique erase  一般是三部曲,来完成功能。

注意在unique后vector的size并没有改变,只是元素的排列改变了,且该函数返回指向一个新序列(就是从序列起始到最后一个元素).的末尾。所以要用erase删除后面的元素。

程序代码如下:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

bool isShorter(const string &s1,const string &s2)
{
    return s1.size()<s2.size();
}
bool GT6(const string &s)
{
    return s.size()>=6;
}

string make_plural(size_t ctr,const string &word, const string &ending)
{
  return (ctr==1) ? word : word+ending;//make_plural(wc, "word ", "s ")当输入中文本中
                                         //word数大于一是在word后加s,为words为word的复数
}
int main()
{
    vector<string> words;
    string next_word;
    while(cin>>next_word)
        words.push_back(next_word);
    sort(words.begin(),words.end());
    vector<string>::iterator end_unique=unique(words.begin(),words.end());
    words.erase(end_unique,words.end());
    //sort words by size,but maintain alphabetic order for words of the same size

    stable_sort(words.begin(),words.end(),isShorter);
    vector<string>::size_type wc=count_if(words.begin(),words.end(),GT6);
    cout<<wc<<"    "<<make_plural(wc,"word","s")<<" 6 characters or longer"<<endl;
    
}

要输出具体的单词,要加上以下代码:

vector<string>::iterator start=find_if(words.begin(),words.end(),GT6);
    for(vector<string>::iterator it=start;it!=words.end();it++)
        cout<<*it<<ends;

count_if 用法如下:

count_if ( ForwardIterator first, ForwardIterator last, Predicate pred );

Returns the number of elements in the range [first,last) for which condition pred is true.