1.vector
vector<int> vec = {1,2,3};
int size = vec.size();
vector<int> vec1;
vec1.resize(3);//申请分配空间
vec1[0]=1,vec1[1]=2,vec1[2]=3;
vector<vector<int>> vec2={{1,0},{0,1}};//二维数组
vector<int> vec3[2];
vec3[0].push_back(1);//在末尾插入一个数据
vec3[0].push_back(0);
vec3[1].push_back(0);
vec3[1].push_back(1);
// 使用迭代器 iterator 访问值
vector<int>::iterator v = vec.begin();
while(v != vec.end()){
printf("value of v = %d\n",*v);
v++;
}
vec.pop_back();//删除最后一个元素
vec.erease(vec.begin(),vec.begin()+1);//删除第一个元素
// 即vector.erase(vector.begin() + 第一个要删除的元素编号, vector.begin() + 最后一个要删除元素的编号 + 1
v = vec.begin();
for(;v<vec.end();v++){
printf("%d ",*v);
}
//查找元素1是否在vec中
if(find(vec.begin(),vec.end(),1)!=vec.end()){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
2.map
#include<map>
//声明一个map数据类型的变量
map<string,int> counter;
//判断某个key是否存在
if(counter.count("hello")==1){
printf("%d\n",counter["hello"]);
}
else{
printf("No Exists!");
}
//清空一个map,主要用在开始一个新的测试用例之前
map.clear()
//对于map可以获得map的迭代器,对其key和value逐一进行访问
map<string,int> Hash;
for(auto it=Hash.begin();it!=Hash.end();it++){
cout<<"key="<<it->first<<","<<"value="<<it->second<<endl;
}
3.string
//string是C++中的头文件
#include <string>
string a;
string b;
int len = a.size();
//字符串切割,从1开始长度为2的字串
a.substr(1,2);
while(cin<<a<<b){
if(a<b){
cout<<a<<endl;
}
else{
cout<<b<<endl;
}
}
在c中对应的代码为
#include <string.h>
char a[100];
char b[100];
int len = strlen(a);
while(scanf("%s%s",a,b)!=EOF){
if(strcmp(a,b)){
printf("%s",a);
}
}
例外除了STL中string类之外,字符数组的常见操作也应该要熟悉;
#include<algorithm>
//将string内的字符统一转化为小写
string s="Hello,World!";
transform(s.begin(), s.end(), s.begin(), ::tolower);
//将string内的字符统一转化为大写
transform(s.begin(), s.end(), s.begin(), ::toupper);
//https://blog.youkuaiyun.com/yasaken/article/details/7303903
#include<string.h>//等价于c++中的<cstring>
char a[10]={'h','e','l','l','o'};
char b[10];
//字符串赋值'0',长度为sizeof(a)
memset(a,'0',sizeof(a));
//获得长度
strlen(a);
//字符串复制(a->b)
strcpy(b,a);
//字符串比较,char-wise,a>b返回1,a<b返回-1,a=b返回0
strcmp(a,b);
4.stack
stack最经典的应用就是左右括号的匹配问题 ,下面以一道例题为例,可以更方便的了解stack的相关操作。
这道题的基本思路就是,从左到右扫描一遍字符串,遇到左括号就把字符的下标压入栈中,遇到右括号就弹出栈顶元素,如果此时栈为空则说明右括号没有匹配上。扫描完字符串之后如果栈不为空,则剩下的均是没有匹配上的左括号。
#include <iostream>
#include <stack>
#include <string.h>
#define N 101
using namespace std;
stack<int> S;
char src[N];
char mark[N];
int main()
{
// printf("%d\n",);
while(gets(src)){
int len = strlen(src);
for(int i=0;i<len;i++)
mark[i]=' ';
for(int i=0;i<len;i++){
if(src[i]=='('){
S.push(i);
}
else if(src[i]==')'){
if(!S.empty())
S.pop();
else{
mark[i]='?';
}
}
}
while(!S.empty()){
int x = S.top();
S.pop();
mark[x]='$';
}
for(int i=0;i<len;i++){
printf("%c",src[i]);
}
printf("\n");
for(int i=0;i<len;i++){
printf("%c",mark[i]);
}
printf("\n");
}
return 0;
}
/*
)(rttyy())sss)(
*/
5.queue
队列最典型的应用就是BFS搜索,用于分层地扩展子节点。
6.heap
C语言中的堆我们可以采用priority_queue来实现
#include<queue>
//大顶堆
priority_queue<int> Q;
//小顶堆
priority_queue<int,vector<int>,greater<int>> Q;
//向堆中插入一个元素
Q.puch(i);
//获得堆顶元素
int x=Q.top();
//弹出堆顶元素(弹出后,Q会自动进行调整成为最小堆)
Q.pop();
//运用与结构体的
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int a;
int b;
Node(int _a,int _b){
a = _a;
b = _b;
}
operator < (const Node& x)const{
if(a!=x.a)
return a<x.a;
else
return b<x.b;
}
};
priority_queue<Node> Que;
int main()
{
Que.push(Node(1,2));
Que.push(Node(1,1));
Que.push(Node(3,6));
while(!Que.empty()){
cout<<Que.top().a<<" "<<Que.top().b<<endl;
Que.pop();
}
return 0;
}
对于堆的使用有的典型的例子就是哈夫曼树,来看如下一例:
题目描述:
哈夫曼树,第一行输入一个数 n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即 weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数 n,接着输入 n 个叶节点(叶节点权值不超过 100,2<=n<=1000)。
输出:
输出权值。
样例输入:
5
1 2 2 5 9
样例输出:
37
来源:
2010 年北京邮电大学计算机研究生机试真题
对于哈夫曼树构建的算法步骤如下:
n个结点组成集合K。
- ①但K中有超过1个结点时,取K中最小的两个结点相加产生一个新的结点并加入到K中
- ②但K中只剩一个结点时,停止Huffman Tree的构建
由于本题要求的是带权路径的长度(对每个结点的路径长度×权重求和),对于哈夫曼树有如下特点:各个叶节点的带权路径长度之和等于非叶节点的权重之和。
代码如下:
#include <iostream>
#include <queue>
using namespace std;
priority_queue<int,vector<int>,greater<int>> Q;
int main()
{
int n,x;
int ans=0;
while(scanf("%d",&n)!=EOF){
while(!Q.empty())Q.pop();
ans=0;
for(int i=0;i<n;i++){
scanf("%d",&x);
Q.push(x);
}
int a,b;
while(Q.size()>1){
a=Q.top(),Q.pop();
b=Q.top(),Q.pop();
Q.push(a+b);
ans+=(a+b);
}
// ans+=Q.top();
printf("%d\n",ans);
}
return 0;
}
/*
5
1 2 2 5 9
*/
7.set
set是STL中表示集合的数据结构,其中存储的每一个元素都是唯一的
#include <iostream>
#include <set>
using namespace std;
set<int> S;
int main()
{
S.insert(100);
S.insert(1);
//删除集合中等于指定数值的元素
S.erase(200);
//1.遍历集合中的元素
for(auto it=S.begin();it!=S.end();it++){
printf("%d ",*it);
}
printf("\n");
//2.遍历集合中的元素
set<int>::iterator it;
for(it=S.begin();it!=S.end();it++){
printf("%d ",*it);
}
printf("\n");
//判空
if(!S.empty()){
printf("集合不为空\n");
//清空集合
S.clear();
}
printf("The size of set is:%d\n",S.size());
set<int> S1;
S1.insert(123);
S1.insert(456);
//交换两个集合中的元素
S.swap(S1);
for(auto it=S.begin();it!=S.end();it++){
printf("%d ",*it);
}
printf("\n");
return 0;
}
8.(algorithm)二分查找函数
max_elment(vec.begin(),vec.end(),cmp)
函数,可以自定义cmp,返回的是否最大元素的指针。
在从小到大的排序数组中,
lower_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound( begin,end,num,greater() ):
从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater() ):
从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
const int INF=2*int(1e9)+10;
#define LL long long
int cmd(int a,int b){
return a>b;
}
int main(){
int num[6]={1,2,4,7,32,34};
sort(num,num+6); //按从小到大排序
int pos1=lower_bound(num,num+6,7)-num; //返回数组中第一个大于或等于被查数的值
int pos2=upper_bound(num,num+6,7)-num; //返回数组中第一个大于被查数的值
cout<<pos1<<" "<<num[pos1]<<endl;//3 7
cout<<pos2<<" "<<num[pos2]<<endl;//4 32
sort(num,num+6,cmd); //按从大到小排序
int pos3=lower_bound(num,num+6,7,greater<int>())-num; //返回数组中第一个小于或等于被查数的值
int pos4=upper_bound(num,num+6,7,greater<int>())-num; //返回数组中第一个小于被查数的值
cout<<pos3<<" "<<num[pos3]<<endl;//2 7
cout<<pos4<<" "<<num[pos4]<<endl;//3 4
return 0;
}