stdlib“唯一”方法不起作用
我正在尝试使用 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;
}
I'm trying to use the C++ Standard Library algorithm unique
(with BinaryPredicate
).
I've created a vector of pairs; each pair is like "(first=a vector of 4 doubles, second=an integer)". The second element serves as index so after using `unique, I can still tell the original index.
In the example below, I've created something like this:
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
Now I want to use the unique function to compare only the first element of each pair. I've used a customize binary predictor uniquepred
. Indeed, it works, but the vector is not reduced after using unique
.
EXPECTED RESULT
Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=1
ACTUAL RESULT
Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=6
Minimum working example follows. Please help me debugging this.
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您想要执行的操作:
这样做的原因是
std::unique
重新排序了值。但它不会删除它们,并且您会留下一个新范围,从begin()
到unique
返回的迭代器。除了重新排序之外,容器本身没有改变。向量上没有“在位置 X 处删除”方法,即使有也会使迭代器无效。
unique
算法的设计甚至不了解底层容器的任何信息,因此它可以与任何有效的迭代器对一起使用。唯一的要求是它们是ForwardIterators。You want to do:
The reason for this is that
std::unique
reorders the values. It doesn't delete them though and you are left with a new range, frombegin()
to the iterator thatunique
returns. The container itself is not altered, other than this reordering.There's no "remove at position X" method on vectors, even if there was it would invalidate the iterators. The
unique
algorithm by design doesn't even know anything about the underlying container, so it can work with any valid pair of iterators. The only requirement is that they areForwardIterators
.std::unique
确实工作;你忘记在你最喜欢的 C++ 库文档中查找它以了解它的作用。它的功能有点奇怪,就像 std::remove 一样,因为它实际上只是移动东西并为您提供新范围的结束迭代器。底层容器未调整大小:您必须自己擦除:
std::unique
does work; you forgot to look it up in your favourite C++ library documentation to find out what it does.It functions a little weirdly, like
std::remove
, in that it actually just moves stuff around and gives you the end iterator to the new range. The underlying container is not resized: you have to do erasure yourself: