C++大牛看看这个STL的编译问题

快乐田伯光 2011-12-15 04:15:49
#include <set>
#include <algorithm>
#include <iostream>
#include <iterator>

struct xxxy : public binary_function<int, int, bool>
{
bool operator() (int a, int b) const
{
return a == b;
}
};

int main(int argc, char *argv[])
{
set<int> set1, set2;
set<int>::iterator iter;

set1.insert(1);
set1.insert(2);
set1.insert(3);
set2.insert(1);
set2.insert(2);

set1.erase(remove_if(set1.begin(), set1.end(), bind2nd(xxxy(), 2)));

copy(set1.begin(), set1.end(), ostream_iterator<int>(cout, " "));

return 0;
}
...全文
213 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamnobody 2011-12-15
  • 打赏
  • 举报
回复
您这样的需求应该使用vector 配合堆算法。
时间复杂度是一样的。
只是insert,erase时比较麻烦点。




int arr[] = {3,2,45,8,7,9};
std::vector<int> vec(arr,arr + 6);
std::make_heap(vec.begin(),vec.end());
std::sort_heap(vec.begin(),vec.end());

vec.erase(std::remove(vec.begin(),vec.end(),8),vec.end());//依然有序。
std::lower_bound(vec.begin(),vec.end(),3);//查找元素。

vec.insert(std::lower_bound(vec.begin(),vec.end(),4),4);//依然有序的插入




快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
上面删个2只是测试程序罢了,实际删的值是满足某一条件的,并不是相等的。
快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
各位,满足条件的在set内部并不一定是连续的, 所以remove_if算法用不了的话,只能自己去遍历加判断了
iamnobody 2011-12-15
  • 打赏
  • 举报
回复

set1.erase(set1.lower_bound(2),set1.upper_bound(4));//删除2 - 4区间内的元素。


这样能满足要求没?
qq120848369 2011-12-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 guosha 的回复:]

这样不行啊,因为这里只是一个测试程序而已,
实际我是需要把符合条件的删除掉。 用find的话跟for(...)加判断差不多了
引用 8 楼 akirya 的回复:

C/C++ code
set1.erase( set1.find(2) );
就行了
[/Quote]

我说的还有点问题, set是不重复键值的, 不用循环erase, 就是find_if就行了。

或者直接set.erase(2)就行了。。。
快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 qq120848369 的回复:]

不行的,remove_if是把符合if的都放到容器末尾,然后返回那一段应该被删除元素的第一个元素的迭代器。

但是set它NND是有序的容器,不是想挪就挪的,make的时候出错提示的挺靠谱的,就是set的键值是const的,不能对*iter1=*iter2这样做。

楼主应该用find_if,循环慢慢erase。
[/Quote]

只能这样喽,多谢!
iamnobody 2011-12-15
  • 打赏
  • 举报
回复
不能这么做的原因是用通用算法修改set中的值,会破坏红黑树的平衡。所以返回const_iterater。也就是说不能直接修改set中的值。只能删除再插入。查找应该用set::find();和set::remove等。
虽然我很奇怪他实现这个方法,但是,抢个分再说
快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
这样不行啊,因为这里只是一个测试程序而已,
实际我是需要把符合条件的删除掉。 用find的话跟for(...)加判断差不多了
[Quote=引用 8 楼 akirya 的回复:]

C/C++ code
set1.erase( set1.find(2) );
就行了
[/Quote]
qq120848369 2011-12-15
  • 打赏
  • 举报
回复
不行的,remove_if是把符合if的都放到容器末尾,然后返回那一段应该被删除元素的第一个元素的迭代器。

但是set它NND是有序的容器,不是想挪就挪的,make的时候出错提示的挺靠谱的,就是set的键值是const的,不能对*iter1=*iter2这样做。

楼主应该用find_if,循环慢慢erase。
  • 打赏
  • 举报
回复
set1.erase( set1.find(2) );
就行了
  • 打赏
  • 举报
回复
set的实现问题,gcc版的 set迭代器不允许赋值,VC 版的是允许赋值的。

而remove_if是需要对迭代器进行赋值。所以gcc下编译不通过。
快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 pqpqr 的回复:]

。。。。。这个声明都不加
[/Quote]

你想说啥啊,帖代码忘贴了而已。如果你可以解决3楼的问题,送你100分,还接受你的不肖的眼神。
iamnobody 2011-12-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 guosha 的回复:]
:!g++ d.cpp
/usr/include/c++/4.1.0/bits/stl_algo.h: In function ‘_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = std::_Rb_tree_……
[/Quote]


我也觉得郁闷死了。。。竟然不合重载的规定。。。
  • 打赏
  • 举报
回复
。。。。。这个声明都不加
快乐田伯光 2011-12-15
  • 打赏
  • 举报
回复
:!g++ d.cpp
/usr/include/c++/4.1.0/bits/stl_algo.h: In function ‘_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = std::_Rb_tree_const_iterator<int>, _OutputIterator = std::_Rb_tree_const_iterator<int>, _Predicate = std::binder2nd<xxxy>]’:
/usr/include/c++/4.1.0/bits/stl_algo.h:1291: instantiated from ‘_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = std::_Rb_tree_const_iterator<int>, _Predicate = std::binder2nd<xxxy>]’
d.cpp:35: instantiated from here
/usr/include/c++/4.1.0/bits/stl_algo.h:1218: error: assignment of read-only location

shell returned 1

有using namespace std的,忘帖了
ouyh12345 2011-12-15
  • 打赏
  • 举报
回复
加了后,在我的vs2008上编译通过
ouyh12345 2011-12-15
  • 打赏
  • 举报
回复
没有
using namespace std;

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧