一、介绍
remove函数原型如下:
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
remove函数会将[first, last)范围内所有等于value的值移动到尾部,返回一个指向新的最后一个元素之后的位置的迭代器,源代码如下:
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
ForwardIterator result = first;
while (first!=last) {
if (!(*first == val)) {
*result = std::move(*first); //移动待删除元素后面的元素
++result;
}
++first;
}
return result;
}
二、实例
测试remove
int main()
{
vector<char> vec = { 'A','A','A','B','C','D','E','A','A' };
// 删除所有的A,执行remove函,返回一个迭代器position
vector<char>::iterator position = remove(vec.begin(), vec.end(), 'A');
// 打印执行remove后,当前数组的值
cout << "执行remove后,当前的数组" << " ";
for (auto ite = vec.begin(); ite != vec.end(); ++ite)
{
cout << *ite << " ";
}
cout << endl;
cout << "remove函数返回的迭代器的值为:"<< *position << endl;
cout << "remove函数返回的迭代器与数组的end迭代器之间的距离为:" << vec.end() - position << endl;
// 打印position 到 vec.end()之间的所有元素
cout << "position 到 vec.end()之间的所有元素为";
for (auto ite = position; ite != vec.end(); ++ite)
{
cout << *ite << " ";
}
cout << endl;
system("pause");
return 0;
}
分析:
读源码我们知道,remove删除的时候只是通过迭代器的指针移动来改变数据的位置,而不是真的删除数组中的数据。所以执行完remove后,打印B C D E C D E A A就很好理解了。当first指针依次移动时,不等于A,result指针就移动,等于A,result指针就停止。然后first指针继续移动一直到循环结束,返回result指针。当fisrt指针走完的时候,result指针正好走到B C D E C D E A A 的位置C(第二个C)这里,所以得到的position为C,距离end指针为5,postiton 到 end之间的序列就是C D E A A。
如果想在数组中真正的删除A,就使用:
vec.erase( remove(vec.begin(), vec.end(), 'A'), vec.end() );
它相当于将result位置开始往后的空间全部释放掉了,得到的就是BCDE。
三、与earse的区别
STL中remove()只是将待删除元素之后的元素移动到vector的前端,而不是删除该元素。若要真正移除,需要搭配使用erase()。
erase的作用是删除掉某个位置position或一段区域(begin, end)中的元素,减少其size,返回被删除元素下一个元素的位置。
删除vector中值为val的元素
vec.erase(remove(vec.begin(),vec.end(),val),vec.end());
举个例子:
删除数组中的重复元素,对数组中的重复元素只保留一个,并且对重复的原地移除。
思路:可以将重复的元素用一个特殊值(比如INT_MAX)替代,再统一删除这个特殊值。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 0){
return 0;
}
int res = 1;
int flag = nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i] == flag) {
nums[i] = INT_MAX;
}
else {
flag = nums[i];
}
}
nums.erase(remove(nums.begin(), nums.end(), INT_MAX), nums.end());
return nums.size();
}
};
int main()
{
vector<int> ans = { 1, 2, 100, 100, 100, 200, 300, 400, 217, 120 };
Solution sol;
sol.removeDuplicates(ans);
for (auto &elem : ans)
{
std::cout << elem << " ";
}
return 0;
}
四、Remove_if()函数
remove_if(beg, end, op) // 移除区间[beg,end)中,每一个“使条件运算:op(elem) == true”的元素;
用法如下:
bool IsSpace(char x) { return x == ' '; } // 判断是否有空格
string str2 = "Text with some spaces";//移除空格
str2.erase(remove_if(str2.begin(), str2.end(), IsSpace), str2.end());
函数原型:
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
first = std::find_if(first, last, p);
if (first != last)
for(ForwardIt i = first; ++i != last; )
if (!p(*i))
*first++ = std::move(*i);
return first;
}
参考:
vector的remove和erase函数的区别_qvector remove_代码码xzy的博客-CSDN博客
C++中remove()函数总结_Toryci的博客-CSDN博客
https://www.cnblogs.com/cthon/p/9223935.htmlh
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)