上篇文章,介绍了C++中find_if的使用,用于在vector在按照自定义的匹配规则查找第一个匹配的数据。
本篇,来介绍另一个类似的函数,remove_if,它用于在vector在按照自定义的匹配规则查找到所有的匹配的数据,并将它们移动末尾。
1 remove_if简介
template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
参数:
ForwardIt:这是一个模板类型参数,代表前向迭代器(Forward Iterator)。
first:指向要处理的元素范围起始位置的前向迭代器。
last:指向要处理的元素范围末尾位置(不包含该位置元素)的前向迭代器。
p:一个一元谓词(Unary Predicate),可以是函数指针、函数对象或者 Lambda 表达式。
返回值:返回一个指向新的逻辑末尾的前向迭代器。新的逻辑末尾是指经过 remove_if 操作后,所有不满足谓词条件的元素之后的位置。
std::remove_if算法会遍历[first, last)范围内的元素,将满足谓词p的元素移动到范围的末尾,同时保持不满足谓词条件的元素的相对顺序不变。注意:
std::remove_if并没有真正从容器中删除元素,只是重新排列了元素的位置。要真正删除元素,需要结合容器的erase方法。
2 示例
2.1 示例一
使用remove_if和rease,查找vector int中所有的偶数并删除
//g++ test1.cpp -std=c++11 -o test1
#include <unistd.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
bool isEven(int num)
{
return num % 2 == 0;
}
void printNumList(std::vector<int> &numberList)
{
for (int &it : numberList)
{
printf("%dn", it);
}
}
int main()
{
printf("hellon");
std::vector<int> numberList = {1, 3, 4, 7, 8, 9};
printf("src numberList size:%zun", numberList.size());
printNumList(numberList);
// 循环查找
for (int &it : numberList)
{
if (isEven(it))
{
printf("find even:%dn", it);
}
}
// 使用 std::remove_if 移除偶数
auto newEnd = std::remove_if(numberList.begin(), numberList.end(), isEven);
printf("do remove_if, now numberList size:%zun", numberList.size());
printNumList(numberList);
if (newEnd != numberList.end())
{
numberList.erase(newEnd, numberList.end());
printf("do erase, now numberList size:%zun", numberList.size());
printNumList(numberList);
}
return0;
}
运行结果:
2.2 示例二
使用remove_if和rease,查找vector Stuent中所有的名字叫LiMing的数据并删除
//g++ test2.cpp -std=c++11 -o test2
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
struct Student
{
std::string id;
std::string name;
};
void printStudentList(std::vector<Student> &studentList)
{
for (Student &it : studentList)
{
printf("studentID:%s name:%sn", it.id.c_str(), it.name.c_str());
}
}
int main()
{
printf("hellon");
std::vector<Student> studentList = {
{"S05001", "LiMing"},
{"S05002", "ZhangHua"},
{"S05003", "LiMing"},
{"S05005", "ZhaoLe"},
};
printf("src studentList size:%zun", studentList.size());
printStudentList(studentList);
std::string studentName = "LiMing";
printf("find name:%s and removen", studentName.c_str());
// 循环查找
for (Student &it : studentList)
{
if (it.name == studentName)
{
printf("find studentID:%s name:%sn", it.id.c_str(), it.name.c_str());
}
}
// find_if方式查找(配合lambda表达式)
auto newEnd = std::remove_if(studentList.begin(),studentList.end(),
[studentName](Student &student){return student.name == studentName;});
printf("do remove_if,now studentList size:%zun", studentList.size());
printStudentList(studentList);
if (newEnd != studentList.end())
{
studentList.erase(newEnd, studentList.end());
printf("do erase,now studentList size:%zun", studentList.size());
printStudentList(studentList);
}
return0;
}
运行结果:
3 总结
本篇介绍了C++中remove_if函数的使用,它用于在vector在按照自定义的匹配规则查找到所有的匹配的数据,结合erase方法实现数据的删除。
3036