OI退役笔记-005:基础知识(一)STL 的使用

总览

C++ 相对于 C 的最大区别就是 C++ 引入了类。而 C++ 的官方就运用类封装了一些模板,称之为“标准模板库” (Standard Template Library)

竞赛常用的标准模板库有:

// 算法库
#include <Algorithm>
// 字符串
#include <string>
// 变长数组
#include <vector>
// 链表
#include <list>
// 队列(普通队列和优先队列)
#include <queue>
// 双端队列
#include <deque>
// 栈
#include <stack>
// 映射
#include <map>
// 二元结构体
#include <pair>
// 集合(有序和无序)
#include <set>

注意:STL 是封装在 std 里的,使用需要引入 std 命名空间。

由于本章涉及的头文件较多,这里统一声明,使用全库且使用 std 命名空间:

#include <bits\stdc++.h>
using namespace std;

Algorithm

Algorithm 总包含很多函数,包括逻辑判断、搜索、复制替换等

1、sort()
Algorithm 里最著名的也许就是 sort() 了,对于 不会写 懒得写排序的人来说绝对是很好的福利。

int a[10] = {9, 2, 4, 2, 6, 8, 3, 5, 0, 7};

main()
{
	sort(a, a + 10);
	for (int i = 0; i <= 9; ++i)
	{
		printf("%d ", a[i]);
	}
}

sort() 会按照升序进行排列。除此之外,sort() 支持自定义 cmp 函数,该功能可实现降序排序及其他数据结构排序。

typedef struct _struct
{
	int a; /* 按照 a 的大小降序排列 */ 
	int b;
} st;

st s[10] = {
{1, 4}, {4, 6}, {3, 43}, {7, 8}, {6, 2}, {2, 7}, {9, 4}, {0, 35}, {8, 21}, {6, 12}, 
};

bool cmp(st st1, st st2)	// cmp 的名称可以自定义,默认最好为 cmp 或 cmp1、cmp2……
{
	return st1.a > st2.a;
}

main()
{
	sort(s, s + 10, cmp);
	for (int i = 0; i <= 9; ++i)
	{
		printf("(%d, %d) ", s[i].a, s[i].b);
	}
}

upper_bound() 和 lower_bound()

lower_bound 返回指向范围中第一个值大于或等于给定值的元素的迭代器
upper_bound 返回指向范围中第一个值大于给定值的元素的迭代器

这个主要可以用于维护单调队列

reverse()
神奇的函数,可以将数组逆序,省下时间。

string str = "0123456789";
main()
{
	reverse(str.begin(), str.end());
	printf("%s", str.c_str());
}

min()、max()、swap() 等
一些在 < cmath > 里的函数在 Algorithm 里都有重新定义。并且都定义在 std 内,不会产生冲突。

其他函数

本人找到了一篇博文有详细介绍,可以参考:
CSDN-博文链接:C++ algorithm函数简介

string

string 真的是无敌牛* 飞天Plus。至少对于我这种不愿意用 cstring 库,不喜欢 字符数组,不会用 不喜欢 char* 的我(好矫情)来说,它无疑是非大常的好用(说都不会话了)

string str;
main()
{
	cin >> str;			// 正确,可以使用 
	
	// 但 scanf("%s", str); 错误,str 不是 C++ 标准的类型,故无法使用
	// 而 string 对于 cin 已经进行了重载,故可以使用
	// 以一下写法也是正确的,不过读入的 str.length() 会等于 0,不建议使用 
	// scanf("%d", str.c_str());

	// 通过下标访问字符串中的字符 [范围:0 ~ length() - 1]
	for (int i = 0; i < str.length(); ++i)
	{
		printf("%c ", str[i]);
	}
	// 输出可以用 printf,但输出整个字符串还需要加上 .c_str()
	// 如 printf("%s", str.c_str()); 
	
	if (str.find('*'))	printf("\nchar \'*\' in string\n");
	// 同样的函数还有 find_first_of、find_first_not_of
	// find_last_of、find_lats_not_of,功能字面理解
	// 找到会返回出现满足条件的字符的位置,如果找不到,会返回 string::nops 
	
	// 替换
	// str.replace(pos, len, str2);
	// str.replace(it1, it2, str2);
	str.replace(1, 3, "不知道写啥了");
	// 等价于 str.replace(str.begin() + 1, str.begin() + 4);
	printf("%s\n", str.c_str());

	// 子串
	// str.substr(pos, len);
	str = "123456";
	printf("%s\n", str.substr(3, 5).c_str()); // 子串 
	
	// 赋值 
	str.assign("1234"); 		// 基础的赋值
	str.assign(4, '*');			// 等价于 str = "****";
	str.assign("1234", 2, 3);	// 将 "1234" 的从 2 开始 到 3 的子串赋值给 str
	// 相当于 str.assign(string("1234").substr())
	
	// 追加字符串 
	str.append("-1=33");
	printf("%s\n", str.c_str()); 
	// append 的用法和 assign 类似 
	
	// str.erase(...) 及 str.insert(...) 的用法类似上面 
	
	// string 支持 <、<=、==、!=、>=、> 
	if (str >= "32")	printf("It is larger than \"32\"\n");
	// string 函数还具有 compare 函数,其功能相当于运算符, 
	// compare 成员函数有以下返回值:
	// 小于 0 表示当前的字符串小;
	// 等于 0 表示两个字符串相等;
	// 大于 0 表示另一个字符串小。
	if (str.compare("32"))	printf("Larger again\n");
	
	// string 有 begin()、end() 两个成员函数返回首尾地址
	// 如 sort(str.begin(), str.end());
}

输出情况
string 也可以使用 流 进行操作,其用 cout 输出原理类似,不多赘述。

vector

Vector 是 C++ 标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。

定义:

// vector<type> val
vector<int> a;				// 一个变长数组
vector<int> b[100];			// 一个维度变长,一个维度定长为 100
vector<vector<double> >c;	// 一个二维变长数组
// 注意,定义多维 vector 时,相邻两个 > 号之间要加空格,防止被判定为右移符号 >>

typedef struct _stu{
	char name[20];
	int age, id;
}stu;

vector<stu> s;				 // 一个变长结构体数组

访问:

第一种:下标访问,不做赘述
第二种:迭代器(类似指针变量)

// vector<typename>::iterator it;
vector<int> a;
vector<int>::iterator it;

...

main()
{
	for (int i = 1; i <= 10; ++i)
	{
		a.push_back(i);
	}
	
	for (int i = 0; i < a.size(); ++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n\n");
	for (it = a.begin(); it != a.end(); ++it)
	{
		printf("%d ", *it);
	}
}

函数:

函数使用
末尾添加 push_back(typename t)v.push_back(41) – O(1)
删除末尾 pop_back(typename t)v.pop_back(41) – O(1)
清空 clear(typename t)v.clear() – O(n)
插入 insert(vector< typename >::itearator it, typename t)v.insert(v.begin() + 2, 41) – O(n)
删除 erase(vector< typename >::itearator it)v.erase(v.begin() + 5) – O(n)
另一种删除使用 erase(vector< typename >::itearator it1, vector< typename >::itearator it2)v.erase(v.begin() + 5, v.begin() + 7) – O(n)

(东西较多,未完)

作者:Rotch
日期:2020-10-01
修改:2020-10-04
[2020-10-04]:修正 String 的使用方法
[2020-10-04]:整理 Vector 的使用方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值