关于STL的使用手册

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值