从容器中删除指定元素
复制、转换和过滤是对一段数据常做的操作。本节,我们将重点放在过滤元素上。
将过滤出的元素从数据结构中移除,或是简单的移除其中一个,但对于不同数据结构来说,操作上就完全不一样了。在链表中(比如std::list
),只要将对应节点的指针进行变动就好。不过,对于连续存储的结构体来说(比如std::vector
,std::array
,还有部分std::deque
),删除相应的元素时,将会有其他元素来替代删除元素的位置。当一个元素槽空出来后,那么后面所有的元素都要进行移动,来将这个空槽填满。这个听起来都很麻烦,不过本节中我们只是想要从字符串中移除空格,这个功能没有太多的工作量。
当我们定义了一个结构体时,我们是不会考虑如何将其元素进行删除的。当需要做这件事的时候,我们才会注意到。STL中的std::remove
和std::remove_if
函数可以给我们提供帮助。
How to do it...
我们将通过不同的方式将vector
中的元素进行删除:
包含必要的头文件,并声明所使用的命名空间。
一个简单的打印辅助函数,用来打印
vector
中的内容:我们将使用简单的整数对
vector
进行实例化。然后,对vector
进行打印,这样就能和后面的结果进行对比:现在,我们移除
vector
中所有的2。std::remove
将2值移动到其他位置,这样这个值相当于消失了。因为vector
长度在移除元素后变短了,std::remove
将会返回一个迭代器,这个迭代器指向新的末尾处。旧的end
迭代器所指向的地方,实际上就没有什么意义了,所以我们可以告诉vector
将这个位置进行擦除。我们使用两行代码来完成这个任务:现在,我们来移除奇数。为了完成移除,我们需要实现一个谓词函数,这个函数用来告诉程序哪些值是奇数,然后结合
std::remove_if
来使用。下一个尝试的算法是
std::replace
。我们使用这个函数将所有4替换成123。与std::replace
函数对应,std::replace_if
也存在于STL中,同样可以接受谓词函数:让我们重新初始化
vector
,并为接下来的实验创建两个空的vector
:然后,我们实现两个判读奇偶数的谓词函数:
接下来的两行做的事情完全相同。其将偶数拷贝到v2和v3中。第一行使用
std::remove_copy_if
函数,当相应数值不满足谓词条件时,函数会从源容器中拷贝到另一个容器中。第二行std::copy_if
则是拷贝满足谓词条件的元素。然后,打印这两个
vector
,其内容应该是完全相同的。编译运行程序。第一行输出的是
vector
初始化的值。第二行是移除2之后的内容。接下来一行是移除所有奇数后的结果。第4行是将4替换为123的结果。最后两行则是v2和v3中的内容:
How it works...
这里我们使用了很多与排序算法相关的函数:
算法函数 | 作用 |
接受一个容器范围和一个具体的值作为参数,并且移除对应的值。返回一个新的end迭代器,用于修改容器的范围。 | |
接受一个容器范围和两个值作为参数,将使用第二个数值替换所有与第一个数值相同的值。 | |
接受一个容器范围,一个输出迭代器和一个值作为参数。并且将所有不满足条件的元素拷贝到输出迭代器的容器中。 | |
与 | |
与 |
Note:
表中没有if的算法函数,都有一个*_if版本存在,其能接受谓词函数,通过谓词函数判断的结果来进行相应的操作。
Last updated