C++ STL基本操作QWQ


系统分配空间耗时与空间大小无关,与申请次数有关


vector

参考连接

支持随机寻址,即 a[i];

#include <vector> // 头文件

// 定义
vector<int> a;
vector<int> a[10]; 
vector<int> a(10, vector<int>(5)); // 创建二维向量

// 定义一个长度为 10 的 vector并将其中的值初始化为 3
vector<int> a(103); 


// 用 vector 初始化

vector<int> b(a); // 直接用 a 初始化 b
vector<int> b(a.begin(), a.begin() + 3); // 将 a 中从 0 开始 三个元素作为 b 的初始值
b = a; // 也可以直接将 a 复制到 b 中

// 用 数组 初始化

int n[] = {1, 2, 2, 4, 5};
vector<int> a(n + 1, n + 4);  // 2 3 4
vector<int> b(&n[2], &n[4]);  // 3 4 => 懂了,括号里要填地址 而非元素值


// a 中元素的 个数	O(1)
a.size();

// a 是否为空	O(1)
a.empty();

// 清空
a.clear();

// 返回 第一个/最后一个 元素
a.front(); 
a.back();

// 在最后插入一个元素 x / 删去最后一个元素
a.push_back(x);
a.pop_back();

// 在某一元素前 插入 n 个元素 x, 不填写插入个数 则默认插入一个
a.insert(a.begin() + 2, 3, 10); // => 在第三个元素前 插入 3 个10
b.insert(b.begin() + 1, a.begin() + 1, a.end()); // 在 b 第一个元素后,插入 a 中第 2 个元素到 最后一个元素
b.insert(b.begin(), n + 1, n + 5); // n 为数组
b.insert(b.begin(), &n[1], &n[5]); // 结果同上(大概)

// 删除
a.erase(a.begin()); // 删除起始位置元素
a.erase(a.begin() + 1, a.begin() + 3); // 删除 第二个位置到第三个位置的元素

// 交换
b.swap(a);

// ☆ 迭代器
a.begin(); // 起始位置
a.end(); // 最后一个元素的 后 一个位置

//遍历方法

for(int i = 0; i < a.size(); i ++ ) 
	cout << a[i] << endl;

for(vector<int>::iterator i = a.begin(); i != a.end(); i ++ )
	cout << *i << endl;

// C++ 关键字 auto 遍历, 效率稍快
for(auto x : a)
	cout << x << endl;

// vector 之间可以直接比较 => 用上面的复制 测试
// 直接从下标 0 开始 按照 字典序 比较
if(a > b) puts("a > b");  // 输出 a <= b
else puts("a <= b");


尽量减少申请空间的次数 => 倍增思想
每次预先开的数组长度不够时,将原先长度乘以 2 ,将之前的元素复制过来
开 2 倍更省时间,1.5 更省空间
具体看 C++ vector的动态扩容,为何是1.5倍或者是2倍

长度为 n 时,申请空间的次数为 log n,且额外复制的效率约为 O(1)


pair

#include <iostream> // 好像写了这个就不用写 utility 了
#include <utility>

using namespace std;

// 定义
pair<Type1, Type2> p; // Type 可以是 int, char, string, long long ... vector 也行
pair<T1, pair<T2, T3> > p;// pair 也可以套娃
pair<T1, T2> p[10];

// 初始化
pair<int, string> p(1, "ab");

pair(int, string> p;
p = make_pair(10, "ab");
p = {20, "cc"};
pair<int, string> p1 = p;

// 调用成员
p.first;
p.second;

// 比较规则
// 先比较 first 中的元素,再比较 second 中的元素
// 不同组成类型的 pair 不能直接进行比较
if( p1.first < p2.first || !(p1.first > p2.first) && p1.second < p2.second) 
	p1 < p2;


String

参考链接

支持随机寻址,如 str[i];

#include <string>

// 定义
string a;

// 初始化
string a("abc");
string a(3, 'h'); // a = "hhh", 好像不能写成 (3, "h");
string a("hahaha", 2, 3); // 从下标 2 开始,长度为 3 的字符串! 3 作为长度,而非结尾下标

a = "hahah";
a = 'h';
string b = a;

// 可以直接与 字符串、字符 相加
a += "haha";
a += 'h';

// 字符串长度
a.length();
a.size();

// 比较规则 => 按照字典序
a < b; // 可直接进行比较

s1.compare(s2); // 当 s1 > s2 时,返回值大于0;
				// 	  s1 == s2时,返回值等于0;
				//	  s1 < s2 时,返回值小于0;
s1.compare(1, 2, s2, 2, 3); // 也可以选择子串相比,s2 也可以直接使用字符串 如"Hello",
							// 这里的 1, 2 表示 下标从 1 开始 长度为 2 的子串,2, 3同理

// 选取子串
s1 = "Xfd big newbee";
s2 = s1.substr(4, 3); // s2 = "big";
s2 = s1.substr(8); // s2 = "big newbee";
s2 = s1.substr(8, 100); // s2 = "big newbee";

// 交换
s1.swap(s2);

// 查找子串 => 找到了返回 子串在s1中起始位置下标;(第一次找到位置)
//			   没找到则返回 string::npos
s1.find("ha"); 
s1.find("ha", 3); // 从下标 3 开始查找
s1.rfind("ha"); // 从后往前查找

s1.find_first_of("fd"); // 第一次出现 f 或 d 的位置
s1.find_last_of("fd"); // 最后一次出现 f 或 d 的位置

s1.find_first_not_of("fd"); // 第一次没有出现 f 或 d 的位置
s1.find_last_not_of("fd"); // 最后一次没有出现 f 或 d 的位置

// 替换子串
s1.replace(1, 3, "abaaba", 2, 4); // 用"abaaba"下标 2 开始 长度为 4 的子串,替换 s1 下标 1 开始 长度为 3 的子串
s1.replace(1, 3, 5, '0'); // 用 5 个 '0' 替换 s1 中子串

// 清空字符串
s.clear();

// 删除子串
s1.erase(1, 3); // 删除 下标 1 开始长度为 3 的子串
s1.erase(3); // 删除下标 3 及以后所有字符

// 判断是否为空
s.empty();

// ☆ 迭代器
str.begin(); // 起始位置
str.end(); // 最后一个元素的 后 一个位置

// 读取空格
getline(cin, s);

// 遍历方法
for(auto x : s1) cout << x << endl;
for(int i = 0; i < s1.size(); i ++ ) cout << x << endl;

printf("%s\n", s.c_str()); // 用 printf 输出 string 的方法


queue

#include <queue>

// 定义
queue<int> q;
queue<int> q[10];

// 元素个数
q.size();

// 队列是否为空
q.empty();

// 向队尾插入元素 x
q.push(x);

// 返回队头 / 队尾 元素
q.front();
q.back();

// 弹出队头元素
q.pop();

// 清空队列 => 没有 clear ,直接重新定义一下
q = queue<int>();


priority_queue

实现

#include <queue>
#include <vector> // 定义小根堆的时候需要

// 定义
priority_queue<Type> q; //默认大根堆
priority_queue<Type> q[10];

priority_queue<int, vector<int>, greater<int> > q; // 小根堆

// 插入一个元素
q.push();

// 返回堆顶元素
q.top();

// 弹出堆顶元素
q.pop();

// 判断是否为空
q.empty();

// 返回队内元素个数
q.size();

// 交换
q.swap(q1);

// 自定义排序规则

// 方式 1
struct node // 运算符重载 < 
{
	int x;
	bool operator < (const node &t) const
	{
	return x > a.x; // 小顶堆
	}
};

priority_queue<node> q;

// 方式 2
struct node2
{
	bool operator() (T1 a, T1 b)
	{
		return a.x > b.x; // 小顶堆
	}
}

priority_queue<T1, vector<T1>, node2> q;

典中典,看病要排队(HDU炸了,想起来再补)


stack

#include <stack>

// 定义
stack<Type> s;

// 向栈顶插入一个元素
s.push();

// 返回栈顶元素
s.top();

// 弹出栈顶元素
s.pop();

// 查询栈中元素个数
s.size();

// 判断栈是否为空
s.empty();


deque

效率超慢
支持随机寻址 q[i]

#include <deque>

// 定义
deque<Type> q;

// 查询大小
q.size();

// 判断是否为空
q.empty();

// 清空
q.clear();

// 查询队头 / 队尾 元素
q.front();
q.back();

// 插入 x
push_front(x); // 向队头插入
push_back(x); // 向队尾插入

// 弹出
pop_front(); // 弹出队头元素
pop_back(); // 弹出队尾元素

// ☆ 迭代器
q.begin();
q.end();


set / multiset

不能含有重复元素
multiset 可以含有重复元素

#include <set>

// 定义
set<Type> s;
multiset<Type> ms;

// 插入一个元素 x
s.insert(x);

// 查找一个元素 x => 查找失败 返回 s.end();
s.find(x);

// 返回某个元素的个数
s.count(x);

// 查询元素个数
s.size();

// 判断 set 是否为空
s.empty();

// 清空
s.clear();

// 删除 x 
s.erase(x); // 删除所有 x   O( k + logn)
s.erase(find(x)); // 也可以删除一个迭代器

// unordered_set / unordered_multyset 不支持该操作
// 不存在的话 返回 s.end()
lower_bound(x); // 返回大于 等于! x 的最小的数 的迭代器
upper_bound(x); // 返回大于 x 的最小的数 的迭代器

set<int> s;
int p = *s.upper_bound(x);
cout << p << endl;


map / multimap

支持随机寻址 , 时间复杂度 O(log n)
也支持 upper_bound 和 lower_bound

#include <map>

//定义
map<Type1, Type2> mp;

// 插入
map<string, int> mp;
mp.insert("abc", 1);
mp["abc"] = 1;

// 删除

// 迭代器删除
mp.erase(mp.find("abc"));

// 关键字删除
mp.erase("abc"); // 删除成功返回 1,否则返回 0

// 迭代器 范围删除
mp.erase(mp.begin(), mp.end()); // 等同于 clear()

// 清空
mp.clear();


unordered_…


unordered_set, unordered_map, unordered_multiset, unordered_multimap

它的内部是无序的(我也不知道能不能遍历。。)
除了不能用 upper_bound 和 lower_bound ,迭代器++ ,- -,之外,基本操作都与上面类似
增删改查的时间复杂度为 O(1);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"c stl基础及应用"是一本关于STL(Standard Template Library,标准模板库)的基础和应用方面的书籍。STL是C++的一个重要的库,它提供了一套标准模板和算法,用于处理数据结构和容器,例如向量、链表、队列、堆等等。 这本书可以帮助读者全面了解STL的基础知识和应用场景。它详细介绍了STL的各种容器、迭代器和算法的使用方法。例如,它会教读者如何创建一个向量,如何在向量中添加和删除元素,如何通过迭代器进行遍历等等。此外,这本书还介绍了STL的常见算法,例如排序、查找和拷贝等。 通过阅读这本书,读者可以学习到如何使用STL来提高程序的效率和可维护性。STL提供了许多高效的数据结构和算法,可以大大简化程序的开发过程。例如,使用STL的排序算法可以让开发者更方便地对数据进行排序操作,节省了编写排序算法的时间和精力。 此外,这本书还提供了一些实际应用的例子,帮助读者将STL的知识应用到实际项目中。这些例子可以帮助读者更好地理解STL的使用,并且在实际编程中能够更灵活地运用STL。 总之,"c stl基础及应用"是一本关于STL的基础和应用方面的书籍,它可以帮助读者系统地学习和理解STL的使用方法,并且通过一些实际例子来加强应用能力。如果对STL感兴趣或者需要使用STL来提高编程效率,这本书将是一个很好的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值