就算法而言,从连续数组中移除一组元素可以在两个部分中有效地完成.
>将所有不要删除的元素移动到数组的前面.
>将数组标记得更小.
这可以使用擦除删除习惯用C在C中完成.
vector<T> v; // v = {0,1,2,3,7}; vector<T>::iterator it = remove(v.begin(),v.end(),e); // move all elements not to be deleted to the front // Yes,remove is not the brightest name for that. // Especially as list::remove really remove elements from the list. // now v = {1,7,?,?} results marked in question marks // are implementation dependent. v.erase(it,v.end()); // get rid of the elements marked as question marks. // v = {1,7}
现在,问号中元素的内容是未知的.我们唯一可以做的就是摆脱它们(通过覆盖它们,或者删除它们).
是否存在真实世界情况,您需要使用删除而不删除?我能想到的唯一情况是
copy(src.begin(),src.end(),remove(v.begin(),e),v.end());
替换所有与Bs一样,要求所有新B都是连续的.没有太多意义.
编辑:除了有名的内存容器(实际上是deque和vector)之外的其他内容是否有意义?
如果我确实是正确的,为什么它作为一个独立的算法实现,而不是vector :: remove_if,dequeue :: remove_if等.
解决方法
你的问题是错误的.相反,人们会问“我为什么要为每个容器重复实现这个相同的算法,而不是让它成为一个单独的自由函数”?
分离容器,迭代器和算法背后的关键思想是,在编写更多算法和更多容器时,不会出现复杂性爆炸.如果要编写具有连续存储的新容器,可以立即使用remove(如果提供转发或随机访问迭代器),而不复制任何代码.
某些容器实现自己的算法成员版本的唯一原因是因为它们可以比通用版本更好(例如std :: set :: find与std :: find;或list :: remove),或者因为他们可以做通用版本不能做的事情(例如std :: list :: sort vs. std :: sort).但是如果可以的话,你应该使用免费版本来获得最大的通用性和通用性.