stdlib“唯一”方法不起作用

时间:2011-09-21 17:29:46

标签: c++ unique stl-algorithm

我正在尝试使用C ++标准库算法unique(带BinaryPredicate)。

我创建了一对对矢量;每对都像“(第一个= 4个双倍的矢量,第二个=整数)”。第二个元素作为索引,因此在使用`unique之后,我仍然可以告诉原始索引。

在下面的例子中,我创建了这样的东西:


10 20 30 40, 1
10 20 30 40, 2
10 20 30 40, 3
10 20 30 40, 4
10 20 30 40, 5
10 20 30 40, 6

现在我想使用unique函数来比较每对的第一个元素。我使用了自定义二进制预测器uniquepred。实际上,它有效,但使用unique后矢量不会减少。

预期结果

Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=1

实际结果

Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=6

以下是最低工作示例。请帮我调试一下。

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

typedef std::vector<double> V1db;
typedef std::pair<V1db, int > Pairs;
typedef std::vector<Pairs> Vpairs;

bool uniquepred( const Pairs& l, const Pairs& r) {
    if (l.first==r.first)
        cout<<"equal!"<<endl;
    return l.first == r.first;
}
int main()
{
    Vpairs ak;
    V1db u2(4);
    u2[0]=10;u2[1]=20;u2[2]=30;u2[3]=40;
    Pairs m2;
    m2.first = u2;
    m2.second= 1;
    ak.push_back(m2);
    m2.second= 2;
    ak.push_back(m2);
    m2.second= 3;
    ak.push_back(m2);
    m2.second= 4;
    ak.push_back(m2);
    m2.second= 5;
    ak.push_back(m2);
    m2.second= 6;
    ak.push_back(m2);
    cout<<"Size before="<<ak.size()<<endl;
    unique(ak.begin(), ak.end(), uniquepred);
    cout<<"Size after="<<ak.size()<<endl;

    return 0;
}

2 个答案:

答案 0 :(得分:9)

你想这样做:

ak.erase(unique(ak.begin(), ak.end(), uniquepred), ak.end());

原因是std::unique重新排序值。它不会删除它们,而是留下一个新的范围,从begin()unique返回的迭代器。除了重新排序之外,容器本身不会被改变。

在向量上没有“在位置X处移除”方法,即使它会使迭代器无效。设计的unique算法甚至不知道底层容器的任何内容,因此它可以与任何有效的迭代器对一起使用。唯一的要求是它们是ForwardIterators

答案 1 :(得分:6)

std::unique 工作;你忘了在你最喜欢的C ++库文档中查找它,看看它是做什么的。

它的功能有点奇怪,比如std::remove,因为它实际上只是移动东西并为你提供新范围的结束迭代器。底层容器没有调整大小:你必须自己擦除:

ak.erase(std::unique(ak.begin(), ak.end(), uniquepred), ak.end());