CSP备考(自用)
vector补充
二维vector数组初始化
vector<vector<int>> matrix(M,vector<int>(N));//初始化一个 二维的matrix, 行M,列N,且值为0
vector<vector<int>>matrix(M);//M行,列数不固定
vector基础操作补充
vector<T> v(v1)//使用 v 中所有元素初始化 v1
vector<T> v(n, val)//v中包含了 n 个值为 val 的元素
vector<T> v(n)//v中包含了 n 个默认值初始化的元素
vector<T> v5{a, b, c...}//使用 a, b, c... 初始化 v5
vector<T> v //v 是一个元素类型为 T 的空 vector
v.back()//返回v中最后一个元素的引用
v.front()//返回v中第一个元素的引用
v1 = v2//用v2中的元素替换v1中的元素
v1 = {a,b,c……}//用元素{a,b,c……}替换v1中的元素
v1 == v2//当且仅当拥有相同数量且相同位置上值相同的元素时,v1 与 v2 相等
v1 != v2
<,<=,>,>=//以字典序进行比较
vector迭代器补充:
一个迭代器的范围由一对迭代器表示,分别为 begin 和 end。其中 begin 成员返回指向第一个元素的迭代器;end 成员返回容器最后一个元素的下一个位置(one past the end),也就是指向一个根本不存在的尾后位置,这样的迭代器没什么实际含义,仅是个标记而已,表示已经处理完了容器中的所有元素。所以 begin 和 end 表示的是一个左闭右开的区间 [ begin , end)
简单升序排序
头文件:
vector//头文件
algorithm//头文件 用来引入sort函数
函数格式:
sort(name.begin(),name.end());
name.begin()表示指向数组头的迭代器,name.end()表示指向数组尾下一个位置的迭代器,该式表示将叫name的vector元素按从小到大进行升序排序。
示例代码:
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
int ans[6]={5,7,3,8,1,2};
vector<int>num;
cout<<"before sorted: ";
for(int i=0;i<6;i++)
{
cout<<ans[i]<<" ";
num.emplace_back(ans[i]);
}
cout<<endl;
cout<<"after sorted: ";
//按升序排序
sort(num.begin(),num.end());
for(int i=0;i<num.size();i++)
{
cout<<num[i]<<" ";
}
system("pause");
return 0;
}
简单降序排序
sort(name.rbegin(),name.rend());
自定义函数排序
sort(res.begin(),res.end(),[&](const typename&a,const typename&b)->bool{
return (输入你的排序标准);
});
示例代码:
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<string>
#include<unordered_map>
using namespace std;
int main(){
//我们将学生信息存入map中
unordered_map<string,int>map;
string name;
int height;
for(int i=0;i<7;i++)
{
cin>>name>>height;
map[name]=height;
}
//将学生名字存入vector数组中
vector<string>res;
for(auto &[key,value]:map)
{
res.emplace_back(key);
}
//自定义排序,按身高降序,身高相同时则按名字升序排列
sort(res.begin(),res.end(),[&](const string&a,const string&b)->bool{
return map[a]==map[b]?a<b:map[a]>map[b];
});
//输出排列后的顺序
cout<<endl;
cout<<"after sorted: "<<endl;
for(int i=0;i<res.size();i++)
{
cout<<res[i]<<" "<<map[res[i]]<<endl;
}
system("pause");
return 0;
}
消除相邻的重复元素
unique()
将输入序列相邻的重复项“消除”,返回一个指向不重复值范围末尾的迭代器,一般配合 sort() 使用
代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void)
{
vector<int> a{2, 0, 2, 2, 0, 3, 0, 9};
sort(a.begin(), a.end()); // 先排序
for(int i:a) cout << i << " "; // 输出
cout << endl;
auto end_unique = unique(a.begin(), a.end()); //将输入序列相邻的重复项“消除”,返回一个指向不重复值范围末尾的迭代器
a.erase(end_unique, a.end()); // 删除末尾元素
for(int i:a) cout << i << " "; // 输出
return 0;
}
// 运行结果 //
0 0 0 2 2 2 3 9
0 2 3 9
vector中找最值
最大值
auto it = max_element(v.begin, v,end())//返回最大值的迭代器
最小值
auto it = min_element(v.begin, v,end())//返回最小值的迭代器
相对位置大小
auto b = distance(x, y)//x、y 是迭代器类型,返回 x、y 之间的距离,可以用来获取最大/小值的索引
代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void)
{
vector<int> a({0,1,-2,3});
auto b = distance(a.begin(), min_element(a.begin(), a.end()));
cout << a[b] << endl;
return 0;
}
// 输出 //
-2
string
头文件
#include<string>
实用string函数
//声明一个字符串
string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
string s(num,c) //生成一个字符串,包含num个c字符
//字符串操作函数
s.insert(pos,args)//在pos之前插入args指定的字符
s.erase(pos,len)//删除从pos开始的len个字符,如果len省略,则删除pos开始的后面所有字符,返回一个指向s的引用
s.assign(args)//将s中的字符替换为args指定的字符。返回一个指向s的引用
s.append(args)//将args追加到s,返回一个指向s的引用,args必须是双引号字符串
s.replace(range,args)//将s中范围为range内的字符替换为args指定的字符
s.find(args)//查找s中args第一次出现的位置
s.rfind(args)//查找s中args最后一次出现的位置
to_string(vall)//将数值val转换为string并返回。fal可以是任何算术类型(int、浮点型等)
stoi(s)/atoi(c)//字符串/字符 转换为整数并返回
stof(s)/atof(s)//字符串/字符 转换为浮点数并返回
s.substr(pos,n)//从索引pos开始,提取连续的n个字符,包括pos位置的字符
reverse(s2.begin(),s2.end())//反转string定义的字符串s2(加头文件<algorithm>)
各个数据结构样例
图
图的邻接矩阵(Adjacency Matrix) 存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。
无向图和其邻接矩阵

- 无向图的邻接矩阵一定是一个对称矩阵(即从矩阵的左上角到右下角的主对角线为轴,右上角的元与左下角相对应的元全都是相等的)。 因此,在实际存储邻接矩阵时只需存储上(或下)三角矩阵的元素。
- 对于无向图,邻接矩阵一定是一个对称矩阵
有向图及其邻接矩阵

对于带权图,对应位置写上权重即可
#define MaxVertexNum 100 //顶点数目的最大值
typedef char VertexType; //顶点的数据类型
typedef int EdgeType; //带权图中边上权值的数据类型
typedef struct{
VertexType Vex[MaxVertexNum]; //顶点表
EdgeType Edge[MaxVertexNum][MaxVertexNum]; //邻接矩阵,边表
int vexnum, arcnum; //图的当前顶点数和弧树
}MGraph;
注意:
在简单应用中,可以直接用二维数组作为图的邻接矩阵
无向图及其邻接表

有向图及其邻接表

相应的存储结构定义
#define MAXVEX 100 //图中顶点数目的最大值
type char VertexType; //顶点类型应由用户定义
typedef int EdgeType; //边上的权值类型应由用户定义
/*边表结点*/
typedef struct EdgeNode{
int adjvex; //该弧所指向的顶点的下标或者位置
EdgeType weight; //权值,对于非网图可以不需要
struct EdgeNode *next; //指向下一个邻接点
}EdgeNode;
/*顶点表结点*/
typedef struct VertexNode{
Vertex data; //顶点域,存储顶点信息
EdgeNode *firstedge //边表头指针
}VertexNode, AdjList[MAXVEX];
/*邻接表*/
typedef struct{
AdjList adjList;
int numVertexes, numEdges; //图中当前顶点数和边数
}
几个经典算法
Dijkstra算法
例图:

具体步骤:

递归示例
public static int Factorial(int num)
{
if(num==1)
{
return num;
}
return num*Factorial(num-1);
}
KMP算法
模式匹配:
当有两个字符串Str = "abdabcde;和 modStr = "abcd";时,如果要在Str中查找与modelStr相等的子串,则称Str为主串,modelStr为模式串。在查找过程中,从Str中的第一个字符进行比较,如果找到与modelStr相同的子串,函数返回modelStr字符串第一次出现的位置,否则返回-1。以上过程就称为模式匹配.
匹配过程:


KMP算法发现每个字符对应的该 k 值仅仅依赖于模式T本身,而与目标对象S无关

因此,next[j]可以预先计算
next[j]表示在第j位失配后,j应该挪到模式串的第几位

KMP代码实现
int KMP(const char* s, const char* p)
{
int ret = -1;
int sLen = strlen(s);
int pLen = strlen(p);
//创建模式字符串的部分匹配表
int* pmt = makePMT(p);
if((pmt != NULL) && (0 < sLen) && (pLen <= sLen))
{
//遍历目标字符串,
for(int i = 0, j = 0; i < sLen; i++)
{
//如果已经有字符匹配,并且s[i]和p[j]不匹配
while((j > 0) && (s[i] != p[j]))
{
//i位置前的pmt[j-1]个字符已经与模式字符串的前pmt[j-1]个字符匹配
j = pmt[j-1];//j回溯到pmt[j-1]处的字符继续比较
}
//如果字符匹配,继续逐位比较
if(s[i] == p[j])
{
j++;
}
//如果找到匹配的字符串
if(j == pLen)
{
//目标字符串中匹配的模式字符串的起始位置索引
ret = i + pLen - 1;
break;
}
}
}
free(pmt);
return ret;
}

浙公网安备 33010602011771号