C++标准库STL的使用

C++标准库STL

一、vector

向量,变长数组

可以以邻接表方式存储图(结点数太多的不行)

1、定义

#include <vector>
using namespace std;

// 定义
vector<typename> name;
vector<typename> arrayname[arraysize];
// 与vector<vector<int> >name;不同的是,这种写法的一维长度已经固定位arraysize,另一维才是变长的。

// typename可以是任何基本类型
// 也可以是STL标准容器,这种的要在定义时在 >> 符号之间加上空格(C++11之前的编译器会将其视为移位操作,导致编译错误)

// e.g.:
vector<int> name;
vector<node> name; // node为结构体
vector<vector<int>> name; // >>之间要加空格
vector<vector<int> > name;

2、访问

下标访问或通过迭代器访问

vector<int> vi;
vector<int>::iterator it = vi.begin();
for(vector<int>::iterator it=vi.begin();it!=vi.end();it++){
	printf("%d ",*it);
}
// vi[i] 和 *(vi.begin() + i) 是等价的
// 允许 i++, ++i

在STL容器中,只有vectorstring允许使用vi.begin()+4这种迭代器+整数的写法。

3、常用函数

1、pull_back()

push_back(x)就是在vector后面添加一个元素x

2、pop_back()

pop_back(x)用以删除vector的尾元素

3、insert()

insert(it, x)用来向vector的任意迭代器it处插入一个元素x

vi.insert(vi.begin()+2,-1);

二、set

1、定义

内部自动有序不含重复元素的容器。

set 内的元素自动递增排序,且去除了重复元素

延申:如果需要处理不唯一的情况,则需要使用 multiset.

C++11 标准还增加了 unordered_set,以散列代替set内部的红黑树(Red Black Tree,一种自平衡二叉查找树)实现,用来处理只去重但不排序的需求,速度比set快很多

#include <set>
set<typename> name;
// e.g.
set<int> name;
set<node> name;
set<typename> Arrayname[arraySize];

2、访问

只能通过**迭代器(iterator)**访问

set<typename>::iterator it;
set<typename> st;
for (set<typename>::iterator it = st.begin(); it != st.end(); it++){
    printf("%d", *it)
}
// 不能使用 it < st.end() 的写法
// 除了vector 和 string 之外的STL容器都不支持 *(it+i) 的访问方式

3、常用函数

1、insert()

insert(x) 可将 x 插入 set 容器,并自动递增排序去重,时间复杂度为 O(logN)

2、find()

find(vlaue) 返回 set 中对应值为 value 的迭代器,时间复杂度为 O(logN)

三、string

字符串容器,对字符串常用的功能进行了封装

#include <string.h> 与 <string>
// 是不同的

1、定义

string str;
string str = "xianyue";

2、访问

  • 下标访问

    string str = "xianyue";
    for (int i=0; i < str.length(); i++) {
        printf("%c", str[i]);
    }
    

    如果要读入或者输出整个字符串,只能使用cincout

    string str;
    cin >> str;
    cout << str;
    

    printf输出string

    string str = "xianyue";
    printf("%s\n", str.c_str());
    // 将string转成字符数组
    
  • 迭代器访问

    string str = "xianyue";
    for (string::iterator it = str.begin(); it != str.end(); it++) {
        printf("%c", *t);
    }
    

    stringvector一样,支持直接对迭代器进行加减某个数字

3、常用函数

1、operator+=

string的加法,拼接字符串

string str1 = "xianyue", str2 = "rrr", str3;
str3 = str1 + str2;
cout<<str3;

2、compare operator

两个string可以直接使用 ==, !=, <, <=, >, >= 比较大小,规则是字典序

3、length() / size()

**length()**返回string的长度,即存放的字符数,O(1)

**size()length()**基本相同

4、insert(),O(N)

  • insert(pos, string),在pos位置插入字符串 string
  • insert(it, it2, it3)it为原字符串的欲插入位置,it2it3是待插入字符串的首尾迭代器

5、substr(),O(len)

str.substr(pos, len);
// 返回从 pos 号位开始,长度为 len 的子串

6、string::npos,是一个常数,本身的值为 -1,由于是 unsigned_int 类型,所以也可以当作 unsigned_int 的最大值。可以作为 find 函数失配时的返回值。

7、find(),O(nm)

str.find(str2);
// 当 str2 是 str 的子串时,返回其在 str 中第一次出现的位置;
// 如果 str2 不是 str 的子串,返回 string::npos

str.find(str2, pos);
// 从 pos 号位开始匹配 str2,返回值与上相同

8、replace(),O(str.length)

str.replace(pos, len, str2);
// 把 str 从 pos 号位开始,长度为 len 的子串替换为 str2

str.replace(it1, it2, str2);
// 把 [it1, it2) 范围内的子串替换为 str2

四、map

映射,可以将任何基本类型映射到任何基本类型。内部是红黑树实现的(set也是),会以 从小到大的顺序自动排序。

如果一个键需要对应多个值,就只能用 multimap,C++11标准还增加了 unordered_map,以散列代替 map 内部的红黑树实现,只映射不排序,速度快得多

#include <map>
using namespace std;

1、定义

map<typename1, typename2> mp;

map<string, int> mp;
// 字符串到整型的映射,必须使用 string,而不能使用 char 数组

map<set<int>, string> mp;

2、访问

  • 通过下标访问 mp[key]

  • 通过迭代器访问

    map<typename1, typename2>::iterator it;
    it->first; // 访问 key
    it->second; // 访问 value
    

3、常用函数

1、find()

find(key) 返回键为 key 的映射的迭代器,O(logN)

map<typename1, typename2> mp;
map<typename1, typename2>::iterator it = mp.find(key);

五、queue

队列,先进先出

双端队列:deque

优先级队列:priority_queue

1、定义

#include <queue>
using namespace std;

queue<typename> name;

2、访问

由于队列先进先出,所以只能通过 front() 来访问队首元素,或者是通过 back() 来访问队尾元素

3、常用函数

1、push()

push(x),将 x 加入队列,O(1)

2、front()、back()

front() / back() 获取 队首 / 队尾 元素,O(1)

3、pop()

pop(),令队首元素出队,O(1)

4、empty()

empty(),检测队列是否为空,O(1)

注意:使用 front() / pop() 前, 必须使用 empty() 判断队列是否为空

六、priority_queue

优先级队列,底层是使用来进行实现的,队首元素一定是当前队列中优先级最高的

1、定义

#include <queue>
using namespace std;

priority_queue<typename> name;
//对于基础类型 默认是大顶堆

2、访问

优先级队列没有 front() 函数 和 back() 函数,只能通过 top() 函数来访问队首元素(堆顶

3、常用函数

1、push()

push(x),令 x 入队,O(logN)

2、top()

top(),获取队首元素,O(1)

3、pop()

堆顶出队

4、empty()

检测队列是否为空

4、优先级设置

基本数据类型

priority_queue<int> q;
priority_queue<int, vector<int>, less<int> > q;
//     这里一定要有空格,不然成了右移运算符↓
priority_queue<int, vector<int>, greater<int> > c;
//这样就是小顶堆
// vector<int> 是承载底层数据结构堆(heap)的容器
// less<int> 是对第一个参数的比较类
// less<int> 表示数字越大优先级越高
// greater<int> 表示数字越小优先级越高

结构体

struct fruit {
    string name;
    int price;
    // 重载运算符
    // 价格高的优先级高
    // 默认是值越小优先级越高
    friend bool operator < (const fruit &f1,const fruit &f2) {
        return f1.price < f2.price;
    }
};
priority_queue<fruit> q;
// or
struct cmp {
    // 价格高的优先级高
    bool operator () (const fruit &f1, const fruit &f2) {
        return f1.price > f2.price;
    }
};
priority_queue<fruit, vector<fruit>, cmp> q;

image-20210402230545841

注意:使用 top() 函数前,必须使用 empty() 判断优先级队列是否为空

七、stack

栈,后进先出

1、定义

#include <stack>
using namespace std;

stack<typename> name;

2、访问

由于栈是一种后进先出的数据结构,所以只能通过top() 来访问栈顶元素

3、常用函数

1、push()

push(x)x入栈,O(1)

2、top(),获取栈顶元素,O(1)

3、pop(),弹出栈顶元素,O(1)

4、empty():检测是否为空,O(1)

八、pair

把两个元素绑在一起,但又不想定义结构体时,pair是一个替代品,也就是说pair可以看作一个内部有两个元素的结构体。

map的内部实现涉及pair。可以作为map 的键值对来插入。

1、定义

#include <utility> // 可以使用 <map>
using namespace std;

pair<typename1, typename2> name;
pair<typename1, typename2> name(value1, value2);

// 临时构建
pair<type1, type2>(value1, value2);
// or
make_pair(value1, value2);

2、访问

pair只有两个元素,分别是 firstsecond,按正常结构体去访问就好

3、常用函数

比较操作数,以<first, second> 元组方式比较

九、algorithm头文件下的常用函数

#include <algorithm>
using namespace std;

1、max()、min()、abs()

max(x, y);
min(x, y);

abs(x);
// x 只能是整数,浮点数的绝对值要使用 math 头文件下的 fabs(x)

2、swap()

swap(x, y);
// 交换 x, y 的值

3、reverse()

reverse(it, it2);
// 将数组指针在 [it, it2) 之间的元素
// 或者容器的迭代器在 [it, it2) 范围内元素
// 进行反转

4、next_permutation()

给出一个序列在全排列中的下一个序列。到达最后一个时返回flase

int a[10] = {1, 2, 3};
do{
    printf("%d%d%d\n", a[0], a[1], a[2]);
} while(next_permutation(a, a+3));

5、fill()

可以把数组容器中的某一段区间赋为某个值。和memset不太一样,fill可以赋范围内的所有值

fill(it, it2, value);
// it - (it2-1) 赋值为 vlaue

6、sort()

排序函数,效率较高。一般不推荐C语言中的qsort(),因为其比较繁琐。

sort规避了经典快排中可能出现的复杂度退化到 O( n 2 n^2 n2) 的极端情况。

STL标准容器中,只有 vectorstringdeque是可以使用 sort。因为像是 setmap这种内部是使用红黑树实现的,元素本身就有序

sort(首元素地址, 尾元素的下一个地址, 比较函数(非必填));
// 默认进行递增排序

bool cmp(int a, int b) {
    return a>b;
    // a>b 时把 a 放在 b 前面
}

// struct 数组的排序
struct node{
    int x, y;
};
// 按 x 的值递减排序
node ssd[10];
bool cmp(node a, node b){
    return a.x > b.x;
}

7、lower_bound() 和 upper_bound()

需要在一个有序数组或者容器中使用。O(log(last-first))

lower_bound(first, last, val);
// 返回 [first, last) 内第一个值大于等于 val 的元素的位置
// 数组返回指针
// 容器返回迭代器

// 如果不存在这样的元素,返回可以插入该元素的 指针 或 迭代器

公共函数

1、clear()

clear()用来清空vector中的所有元素

2、erase()

erase()有两种用法:

  • 删除单个元素:erase(it),删除迭代器处的元素
  • 删除一个区间内的所有元素:erase(first,last),即删除(first,last )区间内的元素

3、size()

size()用来获得vector中元素的个数

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值