目录
一 vector
一 实例
#include<iostream>
//1 头文件:<vector>
#include<vector>
#include<string>
using namespace std;
int main() {
//2 语法:vector<对象类型> 向量名
vector<string> inventory;
//3 使用向量成员函数:.push_back()
/*作用:在向量最后添加一个新元素*/
inventory.push_back("sword");
inventory.push_back("armor");
inventory.push_back("shield");
//4.1 使用向量成员函数:.size()
/*作用:返回向量的大小*/
cout<<"You have "<<inventory.size()<<" items.\n";
cout<<"\nYour items:\n"<<endl;
for(size_t i = 0; i < inventory.size(); ++i)
cout << inventory[i] << endl;
inventory[0] = "battle axe";
//4.2 使用向量成员函数:.size()
/*可以使用下标索引*/
cout<<inventory[0].size()<<endl;
//5 使用向量成员函数:.pop_back()
/*作用:移除向量最后一个元素*/
inventory.pop_back();
//5 使用向量成员函数:.clear()
/*作用:移除向量全部元素*/
inventory.clear();
cout<<"You have "<<inventory.size()<<" items.\n";
//5 使用向量成员函数:.empty()
/*作用:判断向量是否为空*/
if(inventory.empty())
cout<<"You have nothing."<<endl;
else
cout<<"You have at least one item"<<endl;
}
二 要点补充
-
向量可以根据需要增长
-
声明向量的其它方法:
//向量初始大小为 10 vector<string> inventory1(10); //向量大小为 10,且全部(10个)元素都初始化为"nothing" vector<string> inventory2(10, "nothing"); //新向量 inventory3 的内容与 向量 myStuff 相同 vector<string> inventory3(myStuff);
-
不可以 使用下标运算符增加向量的大小
vector<string> inventory; inventory[0] = "sword";//可能出错
三 拓展 二维数组
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int row = 5;
int col = 6;
vector<vector<int>> myVector(row);
for (int i = 0; i < row; i++)
{
myVector[i].resize(col);
}
//输出二维数组
for (int i = 0; i < myVector.size(); i++)
{
for (int j = 0; j < myVector[i].size(); j++)
{
cout << myVector[i][j] << "\t";
}
cout << endl;
}
}
二 迭代器
一 实例
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
vector<string> inventory;
inventory.push_back("sword");
inventory.push_back("armor");
inventory.push_back("shield");
//1 语法:vector<对象类型>::iterator 迭代器名
vector<string>::iterator myIterator;
//2 常量迭代器:不能修改其引用的元素,但自身可以改变
vector<string>::const_iterator iter;
//3.1 使用向量成员函数:.begin()
/*作用:其返回的迭代器引用容器中的第一个元素*/
myIterator = inventory.begin();
//4 修改向量元素的值
*myIterator = "battle axe";
//5 迭代器的解引用
cout << "\nThe item name '" << *myIterator << "' has";
cout << myIterator->size() << " letter in it\n" << endl;
//3.2 使用向量成员函数:.insert()
/*作用:将新元素插入至向量中给定 迭代器引用的元素 之前*/
inventory.insert(inventory.begin() + 1, "crossbow");
//3.3 使用向量成员函数:.erase()
/*作用:移除 迭代器引用的元素*/
inventory.erase(inventory.begin());
cout << "\nYour items:\n";
//3.4 使用向量成员函数:.end()
/*作用:其返回向量中❤️最后一个元素之后❤️的迭代器*/
//6 循环访问向量
for (iter = inventory.begin(); iter != inventory.end(); ++iter)
cout << *iter << endl;
}
二 要点补充
-
使用 push_back( ) 可能使引用向量的所有迭代器失效
-
vector 的成员函数 end( ) 返回的迭代器指向向量最后一个元素之后,而不是最后一个元素
-
对向量调用 insert( ) 成员函数会使引用了插入点之后的元素的迭代器失效,对向量调用 erase( ) 成员函数同理
三 算法
一 实例
//1 头文件:<algorithm>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<vector>
#include<ctime>
using namespace std;
int main() {
vector<int> Scores;
Scores.push_back(7);
Scores.push_back(8);
Scores.push_back(1);
Scores.push_back(6);
vector<int>::const_iterator iter;
int score;
cout << "Finding score" << endl;
cout << "Enter a score to find" << endl;
cin >> score;
//2.1 使用 find() 算法
/*作用:查找目标值*/
//语法:find(开始位置,结束位置,目标值);
iter = find(Scores.begin(), Scores.end(), score);
if (iter != Scores.end())
cout << "Score found" << endl;
else
cout << "Score not found" << endl;
//2.2 使用 random_shuffle() 算法
/*作用:将序列中的元素进行乱序*/
//语法:random_shuffle(开始位置,结束位置)
srand(static_cast<unsigned int>(time(NULL)));
random_shuffle(Scores.begin(), Scores.end());
cout << "Your Scores:" << endl;
for (iter = Scores.begin(); iter != Scores.end(); ++iter)
cout << *iter << endl;
//2.3 使用 sort() 算法
/*作用:对序列中的元素进行升序的排列*/
sort(Scores.begin(), Scores.end());
cout << "Your Scores:" << endl;
for (iter = Scores.begin(); iter != Scores.end(); ++iter)
cout << *iter << endl;
}
四 理解向量的性能
一 实例
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> scores(10, 0);
cout << "\nScores\n";
//使用向量成员函数 .capacity()
/*作用:返回向量的容量*/
cout << "Scores capacity is " << scores.capacity() << endl;//10
cout << "Scores size is " << scores.size() << endl;//10
scores.push_back(1);
//使用向量成员函数 .reserve()
/*作用:将向量的容量扩充至给定实参的大小*/
//scores.reserve(20);
cout << "\nScores were added\n";
cout << "Scores capacity is " << scores.capacity() << endl;//20
cout << "Scores size is " << scores.size() << endl;//11
}
二 要点补充
-
向量的容量和向量的大小(向量容纳的元素的个数)不是一个概念
-
使用 reserve() 将向量的容量维持在足够满足需要, 这样可以将内存的重新分配推迟到某个选定时刻发生
五 其它 STL 容器
一 deque
deque 是双向开口的连续空间
可以理解为deque是双向数组,而vector是单向的
deque在接口上和vector非常相似
1 特性
-
头尾开放,能在头尾进行插入和删除
-
支持随机存储
-
在中段部分插入 删除元素的相对较慢,因为所用元素都需要移动以腾出空间
2 实例
#include<iostream>
#include<deque>
using namespace std;
void Show(deque<string>& Queue)
{
//.empty()
if (Queue.empty())
{
cout << "Please forget it, it has been emptied.\n";
cout << "Now there' nothing in here.\n"
<< "But, it's good!\n" << endl;
return;
}
//.size()
if (1 == Queue.size())
{
cout << "All that's left is the ";
cout << Queue[0] << endl;
return;
}
//迭代器
deque<string>::const_iterator iter;
cout << "\nThere's something in there. Let me see.\n";
cout << "The items have:\n";
for (iter = Queue.begin(); iter != Queue.end(); iter++)
{
cout << *iter << " ";
}
}
void useQueue()
{
cout << "\nUse double-ended queues";
deque<string> Queue;
//.push_back()
Queue.push_back("back");
//.push_front()
Queue.push_front("front");
//.insert()
Queue.insert(Queue.end() - 1, "middle");
Show(Queue);
cout << "\n\nBreak off both ended\n";
Queue.pop_front();
Queue.pop_back();
Show(Queue);
Queue.clear();
Show(Queue);
}
3 常用函数总结
函数 | 功能 |
---|---|
operator= | 将 deque1 的所有元素赋值给 deque2 |
assign(n, element) | 将 n 个 element 副本赋值给 deque |
assign(begin, end) | 将区间 [begin, end] 中的元素赋值给 deque |
deque1.swap(deque2) | 将 deque1 和 deque2 的元素交换 |
swap(deque1, deque2) | 将 deque1 和 deque2 的元素交换,此为全局函数 |
insert(position, element) | 在迭代器 position 所指位置上插入一个 element 副本, 并返回新元素的位置 |
insert(position, n, element) | 在迭代器 position 所指位置上插入 n 个 element 副本, 无返回值 |
insert(position, begin, end) | 在迭代器 position 所指位置上插入 [beg: end) 区间 内的所有元素的副本,无返值 |
push_back(element) | 在尾部追加一个 element 副本 |
pop_back() | 删除最后一个元素(但不返回其值) |
push_front(element) | 在头部插入一个 element 副本 |
pop_front() | 删除第一个元素(但不返回其值) |
erase(position) | 删除迭代器 position 所指元素,返回下一个元素位置 |
erase(begin, end) | 删除区间 [beg: end) 内的所有元素,返回下一个元素位置 |
resize(num) | 将大小改为 n,如果 size() 增长了,新增元素都将从默认构造函数产生出来 |
resize(num, element) | 将大小改为 n,如果 size() 增长了,新增元素都是 element 的副本 |
clear() | 清空容器 |
二 list
使用一个双向链表来管理元素
1 特性
-
不支持随机存储
-
任何位置上,插入与删除元素都很快
-
插入和删除元素的动作不会使其它元素的迭代器、指针、引用失效
2 实例
#include<iostream>
#include<list>
using namespace std;
void Show(list<string>& List)
{
if (List.empty())
{
cout << "Please forget it, it has been emptied.\n";
cout << "Now there' nothing in here.\n"
<< "But, it's good!\n" << endl;
return;
}
if (1 == List.size())
{
cout << "\nAll that's left is the ";
cout << List.back() << endl;
return;
}
list<string>::const_iterator iter;
cout << "\nThere's something in there. Let me see.\n";
cout << "The items have:\n";
for (iter = List.begin(); iter != List.end(); iter++)
{
cout << *iter << " ";
}
}
bool isValue(string& temp)
{
return (temp == "back");
}
void Init(list<string>& List)
{
List.push_back("back");
List.push_front("middle");
List.insert(List.begin(), "front");
List.push_front("front");
List.push_back("back");
}
void useList()
{
//use list
list<string> List;
Init(List);
Show(List);
List.unique();
Show(List);
List.clear();
Init(List);
List.remove_if(isValue);
Show(List);
}
3 插入与删除
函数 | 作用 |
---|---|
list.insert(pos, elem) | 在迭代器pos所指位置上插入一个elem副本,并返回新元素的位置 |
list.insert(pos, n, elem) | 在迭代器pos所指位置上插入n个elem 副本,无返回值 |
list.insert(pos, beg, end) | 在迭代器pos所指位置上插入 [beg: end) 区间内的所有元素的副本,无返值 |
list.push_back(elem) | 在尾部追加一个elem副本 |
list.pop_back() | 删除最后一个元素(但不返回其值) |
list.push_front(elem) | 在头部插入一个elem副本 |
list.pop_front() | 删除第一个元素(但不返回其值) |
list.remove(val) | 删除所有值为val的元素 |
list.remove_if(op) | 删除所有“造成op(elem)结果为true”的元素 |
list.erase(pos) | 删除迭代器pos所指元素,返回下一个元素位置 |
list.erase(beg,end) | 删除区间 [beg: end) 内的所有元素,返回下一个元素位置 |
list.resize(num) | 将元素容量变为num。如果size()变大,则以默认构造函数构造所有新增元素 |
list.resize(num,elem) | 将元素容量变为num。如果size()变大,则以elem副本作为新增元素的初值 |
list.clear() | 删除全部元素,将整个容器清空特殊变动性操作 |
4 list 特色
函数 | 作用 |
---|---|
list.unique() | 如果存在若干相邻而数值相同的元素, 就删除重复元素,只留下一个 |
list.unique(op) | 如果存在若干相邻元素,都使op()的结果为true, 则删除重复元素,只留下一个 |
list1.splice(pos, list2) | 将list2内的所有元素转移到list1之内、迭代器pos之前 |
list1.splice(pos, list2, list2pos) | 将list2内的list2pos所指元素转移到 list1内的pos所指位置上(list1 和list2可相同) |
list1.splice(pos,list2,list2beg,list2end) | 将 list2 内的[list2beg: list2end)区间内所有元素转移到 list1内的pos之前(list1和list2可相同) |
list.sort() | 以operator< 为准则,对所有元素排序 |
list1.merge(list2) | 假设list1和list2容器都包含已排序元素, 将list2的全部元素转移到list1,并保证合并后的list仍为已排序 |
list1.merge(list2,op) | 假设list1和list2容器都包含op()原则下的已排序元素, 将list2的全部元素转移到list1,并保证合并后的list在op()原则下仍为已排序 |
三map
二叉树查找树
map将key/value当作元素(pair),进行管理,可根据key的排序准则自动将元素排序
1 特性
-
key/value 必须可赋值和可复制
-
如若排序,key必须能比较
-
map根据元素key自动对元素进行排序
2 实例
#include<iostream>
#include<map>
using namespace std;
void useMap()
{
map<int, double> Map;
//存储简单易操作
Map[0] = 9.01;
Map[8] = 8.21;
Map.insert(std::pair<int, double>(1, 6.22));
{
cout << Map[1] << endl;
}
cout << endl;
map<int, double>::const_iterator iter;
for (iter = Map.begin(); iter != Map.end(); iter++)
{
cout << iter->second << " ";
}
}
int main()
{
useMap();
return 0;
}
3 基本用法
1 定义>排序
//#include<functional>
map<int, string, std::greater<int>> Mymap;
2 插入
//1
Mymap.insert(std::pair<int, double>(1, 3.14));
//2
Mymap.insert(map<int, double>::value_type(6, 2.333));
//3
Mymap.insert(std::make_pair(4, 8.848));