C++ remove、remove_copy、remove_if和remove_copy_if函数使用详解
有 4 种移除算法:
- remove() 可以从它的前两个正向迭代器参数指定的序列中移除和第三个参数相等的对象。基本上每个元素都是通过用它后面的元素覆盖它来实现移除的。它会返回一个指向新的一个元素之后的位置的迭代器。
- remove_copy() 可以将前两个正向迭代器参数指定的序列中的元素到第三个参数指定的目的序列中,并忽略和第 4 个参数相等的元素。它返回一个指向一个被到目的序列的元素的后一个位置的迭代器。序列不能是重叠的。
- remove_if() 可以从前两个正向迭代器指定的序列中移除能够使作为第三个参数的谓词返回 true 的元素。
- remove_copy_if() 可以将前两个正向迭代器参数指定的序列中,能够使作为第 4 个参数的谓词返回 true 的元素,到第三个参数指定的目的序列中。它返回一个指向一个被到目的序列的元素的后一个位置的迭代器。序列不能是重叠的。
可以按如下方式使用 remove():
sample 中不应包含为 0 的物理测量值。remove() 算通过左移其他元素来覆盖它们,通过这种方式就可以消除杂乱分布的 0。remove() 返回的迭代器指向通过这个操作得到的新序列的尾部,所以可以用它作为被删除序列的开始迭代器来调用 samples 的成员函数 erase()。注释说明容器中的元素没有被改变。std::deque<double> samples {1.5, 2.6, 0.0, 3.1, 0.0, 0.0, 4.1, 0.0, 6.7, 0.0};
samples.erase(std::remove(std::begin(samples), std::end(samples), 0.0), std::end(samples));
std::copy(std::begin(samples),std::end(samples), std::ostream iterator <double> {std::cout," "});
std::cout << std::endl;
// 1.5 2.6 3.1 4.1 6.7
如果想保留原始序列,并生成一个移除选定元素之后的副本,可以使用 remove_copy()。 例如:
samples 容器中的非零元素会被到 edited_samples 容器中,edited_samples 正好是一个 vector 容器。通过 back_insert_iterator 对象将这些元素添加到 edited_samples,因此这个容器只包含从 sample 中的元素。std::deque<double> samples {1.5, 2.6, 0.0, 3.1, 0.0, 0.0, 4.1, 0.0, 6.7, 0.0}; std::vector<double> edited_samples;
std::remove_copy(std::begin(samples), std::end(samples), std::back_inserter(edited_samples), 0.0);
remove_if() 提供了更强大的能力,它能够从序列中移除和给定值匹配的元素。谓词会决定一个元素是否被移除;它接受序列中的一个元素为参数,并返回一个布尔值。例如:
这段代码用来模拟候选人申请成为倶乐部会员。那些众所周知的不安分人士的姓名被保存在 blacklist 中,它是一个。当前申请成为会员的候选人被保存在 candidates 容器中,它是一个 deque 容器。用 remove_if() 算法来保证不会有 blacklist 中的姓名通过甄选过程。这里的谓词是一个以引用的方式捕获 blacklist 容器的 lambda 表达式。当参数在容器中存在时,set 容器的成员函数 count() 会返回 1。谓词返回的值会被隐式转换为布尔值,因此对于每一个出现在 blacklist 中的候选人,谓词都会返回 true,然后会将它们从 candidates 中移除。注释中显示了通过甄选的候选人。using Name = std::pair<string, string>; // First and second name
std::set<Name> blacklist {Name {"Al", "Bedo"}, Name {"Ann", "Ounce"}, Name {"Jo","King"}};
std::deque<Name> candidates {Name{"Stan", "Down"}, Name {"Al", "Bedo"}, Name {"Dan", "Druff"},Name {"Di", "Gress"}, Name {"Ann", "Ounce"}, Name {"Bea", "Gone"}}; candidates.erase(std::remove_if(std::begin(candidates), std::end(candidates),[&blacklist](const Name& name) { return blacklist.count(name); }), std::end(candidates)); std::for_each(std::begin(candidates), std::end(candidates), [] (const Name& name){std::cout << '"' << name.first << " " << name.second << "\" ";});
std::cout << std::endl; // "Stan Down" "Dan Druff" "Di Gress" "Bea Gone"
remove_copy_if() 之于 remove_copy(),就像 remove_if() 之于 remove。下面展示它是如何工作的:
这段代码实现了和前一段代码同样的功能,除了结果被保存在 validated 容器中和没有修改 candidates 容器之外。std::set<Name> blacklist {Name {"Al", "Bedo"}, Name {"Ann", "Ounce"}, Name {"Jo", ,"King" } };
std::deque<Name> candidates {Name {"Stan", "Down"}, Name { "Al", "Bedo"},Name {"Dan", "Druff"}, Name {"Di", "Gress"}, Name {"Ann", "Ounce"},Name {"Bea", "Gone"}};
std::deque<Name> validated;
std::remove_copy_if(std::begin(candidates) , std::end(candidates), std::back inserter(validated), [&blacklist] (const Name& name) { return blacklist.count(name); });
- 随机文章
- 泰山 稻城 马尔代夫(泰山稻城马尔代夫,世界之最。)
- 增城市马尔代夫(增城市打造现代化马尔代夫旅游海岛闪亮登场)
- 国足 马尔代夫 战绩表(国足于马尔代夫获得优异战绩)
- 平凉马尔代夫在哪(平凉市一旅行社开通直飞马尔代夫航班)
- 六一马尔代夫旅游(儿童节马尔代夫游,尽享海滩阳光美食)
- 东莞马尔代夫集市(东莞集市变身马尔代夫,吸引众多游客)
- 广州马尔代夫人均(广州人去马尔代夫,旅游花费重磅揭晓)
- 马尔代夫飞机拍摄(壮观!从天上俯瞰马尔代夫岛屿美景)
- 山西马尔代夫沙滩(山西旅游局推出马尔代夫沙滩主题活动)
- 曲阳马尔代夫文案(极致浪漫之旅,曲阳马尔代夫等你来!)
- 柬埔寨的马尔代夫(后的:柬埔寨:东南亚的新马尔代夫?)
- 咸阳马尔代夫月季(咸阳市私家花园成功种植马尔代夫月季)
- 马尔代夫马累费用(探寻马尔代夫首都马累旅游费用攻略)
- 杭州马尔代夫风景(杭州打造海底世界,创新马尔代夫风情)
- 摩纳哥到马尔代夫(从欧洲到印度洋:摩纳哥飞往马尔代夫)
- 踢马尔代夫控球率(踢马尔代夫控球率居高不下,豪取胜利)
- 胶州马尔代夫改造(胶州湾打造仿佛在马尔代夫的度假胜地)
- 翡翠马尔代夫玫瑰(马尔代夫玫瑰:翡翠开辟全新度假天堂)
- 邢台马尔代夫河滩(邢台市民自驾游马尔代夫沙滩惬意畅游)
- 适合亲子马尔代夫(带娃去马尔代夫游,畅玩海岛亲子乐!)
- 病毒营销马尔代夫(马尔代夫旅游行业变革:病毒营销现身)
- 天合 马尔代夫(天合集团在马尔代夫展开新业务)
- 马尔代夫伊塔餐厅(马尔代夫新开餐厅伊塔,菜品丰富多样)
- 马尔代夫南方航空(马尔代夫南方航空公司新路线即将开通)
- 马尔代夫印度雷达(马尔代夫安装印度雷达,提升海上安全)
- 马尔代夫下方岛国(后的:马尔代夫下沉的岛国面临的挑战)
- 马尔代夫场景介绍(探索马尔代夫美景,品味独特自然之美)
- 离开马尔代夫感言(太美好了!马尔代夫之旅让人难以忘怀)
- 阳江 马尔代夫(阳江度假区与马尔代夫签署合作协议,打造国际旅游胜地)
- 马尔代夫夺冠记录(马尔代夫成功夺得冠军,创下历史记录)
