评论

STL 官网学习笔记—— unique

STL 官网学习笔记—— unique

1、unique,顾名思义,就是给容器内的连续的元素去重,这些连续重复的元素中只保留最前面的那一个

  • 注意1:只有当遇到连续重复的元素,它才会起到去重作用,如果是{1, 2, 1},则unique不能对其进行去重
  • 注意2:unique操作不会减少容器的长度,它只是将保留下来的元素从头一一覆盖到容器中去,多出来的部分依旧是可以访问的,这部分需要你自行去删除

2、unique是稳定的,去重后,剩余的元素顺序是不变的

3、需要头文件:algorithm

4、unique有两个方法,一个是用默认的方式来定义重复元素,另一种是以自定义方式来判断是否是重复元素

[first, last)表示容器中需要去重的范围,返回值是一个前向指针,指向去重后的最后一个有效元素的下一个位置iter,你可以通过删除

[iter, end) ,保留[first, iter),来达到去重效果

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

以上这个方法,如果有连续的元素都满足彼此相等,或者指向的对象相等,则为重复元素

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

以上这个方法,如果有连续的元素都满足彼此相等,或者它们指向的对象在自定义的二元谓词的作用下依旧为true,binary_pred(*i, *(i-1)) == true,则为重复元素

5、由于unique只能给连续的重复元素去重,采用 sort 与 unique 方法结合的方式,去重效果更佳

6、小示例

#include<iostream>
#include<iterator>
#include<algorithm>
#include<vector> 
#include<list>
using namespace std;

inline bool eq_nocase(char c1, char c2) { return tolower(c1) == tolower(c2); }
inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); }

int main()
{
    // 运用默认方法来去重,直接去重可能达不到最佳效果 
    vector<int> V1;
    V1.push_back(1);
    V1.push_back(3);
    V1.push_back(3);
    V1.push_back(3);
    V1.push_back(2);
    V1.push_back(2);
    V1.push_back(1);
    vector<int>::iterator new_end1 = unique(V1.begin(), V1.end());
    copy(V1.begin(), new_end1, ostream_iterator<int>(cout, " "));
    cout<<endl; 
    cout << endl;
    
    // 采用 排序 与 unique 方法结合的方式,去重效果更佳 
  const char init[] = "The Standard Template Library";
  vector<char> V(init, init + sizeof(init));
  // 调用sort进行排序 
  sort(V.begin(), V.end(), lt_nocase);
  copy(V.begin(), V.end(), ostream_iterator<char>(cout));
  cout << endl;
  // 进行去重,运用自定义的方法来忽略大小写问题 
  vector<char>::iterator new_end = unique(V.begin(), V.end(), eq_nocase);
  copy(V.begin(), new_end, ostream_iterator<char>(cout));
  cout << endl;
  cout << endl;
  
  
  // 去重成功,但后面的元素依旧还在 
   copy(V.begin(), V.end(), ostream_iterator<char>(cout));
   cout << endl;
   // 删除它们
   V.erase(new_end, V.end());
   copy(V.begin(), V.end(), ostream_iterator<char>(cout));
   cout << endl;
   cout << endl;
   
   // 补充:list.unique方法是可以减少容器长度的 
   int a[] = {1, 1, 4, 5, 5, 4, 5};
   list<int> s(a, a + 7);
   s.unique();
   copy(s.begin(), s.end(), ostream_iterator<int>(cout, " "));
}

运行结果:

点赞 0
收藏
评论
登录 后发表内容