今天我们继续更新 C++ STL 中 vector 容器的使用
vector 容器删除元素
使用 clear() 函数可以删除容器内的所有元素。
示例如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","two","three","four","five"};
//将 data 复制给 data_
vector<string> data_(data);
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
cout<<"data_: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<" ";
}
cout<<endl;
//使用 clear() 清除 data_ 所有元素
data_.clear();
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
cout<<"data_: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<" ";
}
cout<<endl;
return 0;
}
结果如下:
使用成员函数 pop_back() 来删除容器尾部的元素。
示例如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","two","three","four","five"};
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
data.pop_back();
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
return 0;
}
结果如下:
可以使用成员函数 erase() 可以删除容器中的一个或多个元素。如果只删除单个元素,那么只需要提供一个参数,例如:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","two","three","four","five"};
//迭代器指向第 0 个元素
auto iter_goal = begin(data);
//删除第 0 个元素,返回被删除元素的后一个元素
auto iter = data.erase(iter_goal);
cout<<*iter<<endl;
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
//迭代器指向最后一个元素
iter_goal = end(data);
iter = data.erase(iter_goal);
auto p = end(data);
cout<<&iter_goal<<" "<<&iter<<" "<<&p<<endl;
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
return 0;
}
结果如下:
删除一个元素后,vector 的大小减 1,会返回一个迭代器,它指向被删除元素后的一个元素。
如果要移除一个元素序列,只需要传入两个迭代器,用来指定移除元素的范围。
不要忘记,第二个迭代器指向这段元素末尾的下一个位置。
上面的语句删除了 begin_iter 和 end_iter 的元素。
示例如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","two","three","four","five"};
vector<string> data_(data);
vector<string>::iterator begin_iter = begin(data);
auto end_iter = end(data);
begin_iter++,end_iter--;
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
//删除第一个元素到倒数第二个元素
auto iter = data.erase(begin_iter,end_iter);
cout<<*iter<<endl;
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
//删除第二个到最后一个元素
begin_iter = begin(data_);
end_iter = end(data_);
cout<<"data_: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<" ";
}
cout<<endl;
begin_iter++;
data_.erase(begin_iter,end_iter);
cout<<"data: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<" ";
}
cout<<endl;
return 0;
}
结果如下:
remove() 函数存在于 algorithm 头文件中,它可以删除匹配特定值的一段元素。
示例如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","null","three","four","null","six","seven"};
vector<string> data_(data);
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
auto begin_iter = begin(data);
auto end_iter = end(data);
remove(begin_iter,end_iter,"null");
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<endl;
}
cout<<endl;
return 0;
}
结果如下:
remove(begin_iter,end_iter,"null");
语句的第一,二个参数指定的元素范围内,移除了所有匹配 remove() 的第三个参数 "null" 的元素。
严格来说,remove() 并不是移除元素,它没有删除容器中的元素。remove() 移除元素的方式和从字符串中移除空格的方式相似,都是通过用匹配元素右边的元素来覆盖匹配元素的方式移除元素。
简单演示如下:
"one" "null" "three" "four" "null" "six" "seven"
索引为 1 处是 "null",将 "null" 右边的元素向左移
"one" "three" "four" "null" "six" "seven" ""
注意:"" 不代表此处为空字符串,而是原有 "six" 移动后留下的空位。空间存在,却没有元素。
之后再发现一个 "null",移动元素后
"one" "three" "four" "six" "seven" "" ""
我们发现,remove 函数并不能真正删除元素,而且容易出现一些意料之外的问题,因此可以结合 erase() 函数来删除元素。
示例如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<string> data {"one","null","three","four","null","six","seven"};
vector<string> data_(data);
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<" ";
}
cout<<endl;
auto begin_iter = begin(data);
auto end_iter = end(data);
auto iter = remove(begin_iter,end_iter,"null");
data.erase(iter,end(data));
cout<<"data: "<<data.size()<<endl;
for(auto d : data){
cout<<d<<endl;
}
cout<<"erase-remove: "<<endl;
cout<<"data_: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<endl;
}
data_.erase(remove(begin(data_),end(data_),"null"),end(data_));
cout<<"data_: "<<data_.size()<<endl;
for(auto d : data_){
cout<<d<<endl;
}
return 0;
}
结果如下:
解释:
erase 和 remove 相结合的方式,执行删除操作后,iter 指向最后一个元素之后的位置,所以它标识了被删除序列的第一个元素,被删除序列的结束位置由
end(data) 指定。
当然,在一条语句中,也能先移除元素,然后再删除末尾不想要的元素
remove() 函数返回的迭代器作为 erase() 的第一个参数,erase() 的第二个参数是所指向容器中最后一个元素后一个位置的迭代器。
至此,vector 容器的一些常见使用到此结束,这里只介绍了 vector 的基本使用,之后在 stl 算法部分还会介绍其他用法,最后将简单总结 vector 容器,并结合一些题来补充 vector 的其他知识以及运用。