vector容器 std::unique函数的实现

源于《挑战程序设计竞赛》第164页程序中调用的函数unique, 今天好好看看。 

该函数std::unique位于头文件<algorithm>声明1如下:

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

声明2如下:

template< class ForwardIt, class BinaryPredicate >  
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPredicate p );  


该函数的作用为: 删除[first, last)之间所有连续重复的元素, 只保留一个。 注意, 是连续重复。 要删除所有重复的元素, 只需要排序之后, 然后调用这个函数即可实现。 第一个版本通过==判断是否重复, 第二个版本通过二元谓词p判断是否重复。 

二元谓词p, 就是binary predicate which returns ​true if the elements should be treated as equal. 

版本1的可能的实现方式:


template<class ForwardIt>  
ForwardIt unique(ForwardIt first, ForwardIt last)  
{  
    if (first == last)  
        return last;  
   
    ForwardIt result = first;  
    while (++first != last) {  
        if (!(*result == *first)) {  
            *(++result) = *first;  
        }  
    }  
    return ++result;  
}  

所一, 最终返回的一个迭代器指向任务结束的位置past the end.
版本二的实现方式:


template<class ForwardIt, class BinaryPredicate>  
ForwardIt unique(ForwardIt first, ForwardIt last,   
                       BinaryPredicate p)  
{  
    if (first == last)  
        return last;  
   
    ForwardIt result = first;  
    while (++first != last) {  
        if (!p(*result, *first)) {  
            *(++result) = *first;  
        }  
    }  
    return ++result;  


测试程序如下:


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

using namespace std;

int main() {
    vector<int> ivec;//{1, 2, 2, 2, 3, 3, 2, 2, 1};
    ivec.push_back(1);
    ivec.push_back(2);
    ivec.push_back(2);
    ivec.push_back(2);
    ivec.push_back(2);
    ivec.push_back(2);
    ivec.push_back(3);
    ivec.push_back(1);
    ivec.push_back(3);



    vector<int>::iterator last;
    last = unique(ivec.begin(), ivec.end());

    for(vector<int>::iterator it = last; it != ivec.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    // 注意上述的输出, ivector 的size 并没有变。

    //removes all duplicate elements from a
    //vector of integers.
    vector<int> ivec2;//{1, 2, 2, 2, 3, 3, 2, 2, 1};
    ivec2.push_back(1);
    ivec2.push_back(2);
    ivec2.push_back(2);
    ivec2.push_back(2);
    ivec2.push_back(2);
    ivec2.push_back(2);
    ivec2.push_back(3);
    ivec2.push_back(1);
    ivec2.push_back(3);
    sort(ivec2.begin(), ivec2.end());
    vector<int>::iterator last2;
    last2 = unique(ivec2.begin(),ivec2.end());

    for(int i = 0;i<ivec2.size();i++) {
        cout << ivec2[i] << " ";
    }
    cout << endl;
    // 删除last2 到 ivec2.end() 的所以的元素
    ivec2.erase(last2, ivec2.end());
   // cout << ivec2.capacity() << endl; capacity 仍然为9, 只能用swap释放占用的内存了
    for(int i = 0;i<ivec2.size();i++) {
        cout << ivec2[i] << " ";
    }
    cout << endl;
    // 类似的见unique_copy
    return 0;
}

运行结果如下:

2 3 1 3 
1 2 3 2 2 2 2 3 3 
1 2 3 
[Finished in 0.4s]




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值