在算法竞赛中,我们经常要用到c++所内置提供的容器来解决问题,今天我们就简单介绍三种容器的具体应用
这个单词的本意应该是向量,在实际运用的过程中我们通常认为他是一个无限长的数组,至于他为什么能无限的原理,应该是开始先申请一个长度为n的空间,空间填满后,继续申请一个长度为2n的空间,将之前空间的内容复制下来,依次类推,保证不会爆空间
关于vector的基本操作有如下几种
1.初始化
1.初始化少量数据:列表初始化vector<type>a={1,2,3};等价于vector<type>a{1,2,3};
2.向量复制:vector<type>a=b;等价于vector<type>a(b);
3.初始化重复数据:vector<type>a(10,1);意为创建一个含有10个整型元素1的向量类型数据。
2.常用功能
vector<int> v;
v.push_back(1);
v.empty();//判断是否为空,返回一个bool值
v.size();
v.erase(v.begin() + 3); //删除第四个元素,括号内应为迭代器
v[n];//直接调用
3.遍历数组方法
vector<int> v;
for(int i=0;i<s.size();i++)
cout<<v[i]<<endl;
vector<int>::iterator beg = v.begin(); //指向容器的第一个元素
vector<int>::iterator ed = v.end(); //指向容器 尾元素的 下一个位置!注意是下一个位置
for (vector<int>::iterator it = beg; it != ed; ++it)
cout << *it << endl;
如果不想定义迭代器可以直接在循环中用auto it=v.begin()代替,系统会自动识别it的类型为迭代器
for (auto &e : v)
{
cout << e << endl;
}
set是一个用二叉搜查数维护的容器,它的功能就是维护一个排好序的每个数只出现一次的有序集合
,我们可以从中删除任意位置的元素并set会自动复原,关于set的操作大概有以下几种
begin() 返回set容器的第一个元素的地址
end() 返回set容器的最后一个元素地址
clear() 删除set容器中的所有的元素
empty() 判断set容器是否为空
max_size() 返回set容器可能包含的元素最大个数
size() 返回当前set容器中的元素个数
erase(it) 删除迭代器指针it处元素
insert(a) 插入某个元素
find()
大部分操作类似于vector
重点强调删除和查找操作
1.关于删除操作我们可以用2种方式进行
erase(iterator) ,删除迭代器iterator指向的值
erase(first,second),删除迭代器first和second之间的值
erase(key_value),删除键值key_value的值
也就是直接删除key-value和删除某个地址的方式进行。
2.关于查找操作
find()
需要注意的是find函数返回的值类型是一个迭代器,也就是该元素的地址在输出是应该前加*
set<int> a;
a.insert(1);
a.insert(3);
a.find(3);
int main()
{
int a[] = {1,2,3};
set<int> s(a,a+3);
set<int>::iterator iter;
if((iter = s.find(2)) != s.end())
cout<<*it<<endl;
return 0;
}
s.lower_bound(key_value) ,返回第一个大于等于key_value的迭代器
s.upper_bound(key_value),返回最后一个大于等于key_value的迭代器
如果set里是结构体那么我们需要重载运算符
struct Info
{
string name;
float score;
//重载“<”操作符,自定义排序规则
bool operator < (const Info &a) const
{
//按score从大到小排列
return a.score<score;
}
}
set<Info> s;
......
set<Info>::iterator it;
map的意义在于他可以建立一个一对一的key对value的映射,可以简单理解为可以自定义下标的数组,key的值只能出现一次,第二次定义会覆盖第一次的定义
基本操作
1插入数据
// 定义一个map对象
map<int, string> m;
// 第一种 用insert函數插入pair
m.insert(pair<int, string>(000, "student_zero"));
// 第二种 用insert函数插入value_type数据
m.insert(map<int, string>::value_type(001, "student_one"));
// 第三种 用"array"方式插入
m[123] = "student_first";
m[456] = "student_second";
需要注意的是如果采用第一种方法那么对同一个key赋值2次最后结果是第二次赋值无效
而第三种方法则是第一次赋值被覆盖,第二次赋值有效
**基本用法
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
erase() 删除一个元素
find() 查找一个元素
insert() 插入元素
size() 返回map中元素的个数
swap() 交换两个map
lower_bound() 返回键值>=给定元素的第一个位置
upper_bound() 返回键值>给定元素的第一个位置
其中find和erase针对的对象都是map中的key值的迭代器
find()的使用
在map中
(*it).first会得到key,
(*it).second会得到value。
这等同于it->first和it->second。
map<int, string>::iterator it;
it = m.find(1);
if (it == m.end()) {
cout << "not found !" << endl;
}
else {
cout << it->second << " is found " << endl;
}
//另外一种查找方式
if (m.count(10) != 0)
cout << m[10] << " is found \n";
else
cout << "not found !\n";
earse()的使用
//迭代器刪除
it = m.find("123");
m.erase(iter);
//用关键字刪除
int n = m.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范围刪除 : 把整个map清空
m.erase(m.begin(), m.end());
//等同于m.clear()
map中元素的遍历
//遍历一遍所有元素
cout << "\n遍历所有元素: \n";
for (it = m.begin(); it != m.end(); ++it) {
printf("%d: %s\n", it->first, it->second);
}