C++ Standard Template Libarary(STL)

本文详细介绍了C++的Standard Template Library (STL) 的六大部件:容器、分配器、算法、迭代器、适配器、仿函数,并重点讲解了包括Vector、Stack、Queue、Priority_Queue、Deque、List、Set、Map等核心容器的特性和使用场景。此外,还提到了next_permutation()函数用于求解排列组合的问题。
摘要由CSDN通过智能技术生成

STL

概述

STL六大部件: 容器、分配器、算法、迭代器、适配器、仿函数

  • 容器: 用来存放数据
  1. Sequence Container(循序式容器):排列次序取决于插入时机和位置
    array(c++11)、vector、 stack、queue、deque、 priority_queue、list
  2. Associative Container(关联式容器):排列次序取决于特定准则
    set/multimap 、map /multimap
  • 适配器: 一种接口类,为已有的类提供新的接口,目的是简化、约束、使之安全、隐藏或者改变被修改类提供的服务集合;(三种类型的适配器)
    1. 容器适配器:用来扩展7种基本容器,它们和顺序容器相结合构成栈、队列和优先队列容器
    2. 迭代器适配器(反向迭代器、插入迭代器、IO流迭代器)
    3. 函数适配器(函数对象适配器、成员函数适配器、普通函数适配器)
  • 算法:    计算数据
  • 迭代器:访问数据的式(算法使用其访问容器内大数据)
  • 仿函数 :类似于函数的功能

六大部件的使用实例:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
using namespace std;
int main ()
{
	int ia[6]={27,210,12,47,109,83};
	vector<int,allocator<int> > vi(ia,ia+6);
	cout<<count_if(vi.begin(),vi.end(),not1(bind2nd(less<int>(),40)));
	return 0;
 } 

容器

容器区间都是左闭右开的;

Vector: 动态数组,运行时根据需要改变数组大小。

  • 以数组形式存储,内存空间是连续的,索引可以在常数时间内完成。
  • 但是在中间进行插入和删除操作,会造成内存块的拷贝。
功能例子说明
定义int型数组vector a;默认初始化,a为空
vector b(a);a有100个值为0的元素
vector a(100, 6);100个值为6的元素
定义string型数组vector a(10,”null”);10个值为null的元素
vector vec(10,”hello”);10个值为hello的元素
vectorb(a.begin(), a.end());b是a的复制
定义结构型数组struct point { int x, y;};

vector a;
a用来存坐标

在这里插入图片描述
实例:圆桌问题

#include<bits/stdc++.h>
using namespace std;
int main(){
    vector <int> table; //模拟圆桌
    int n, m		
    while(cin >> n >> m)
    {
        table.clear();	
        for(int i=0; i<2*n; i++)  	table.push_back(i);  //初始化
        int pos = 0; //记录当前位置
        for(int i=0; i<n; i++)   //赶走n个
       {            
	pos = (pos+m-1) % table.size();    
	//圆桌是个环,取余处理
	table.erase(table.begin() + pos); 
	//赶走坏人,table人数减1
       }
        
      int j = 0;  
      for(int i=0; i<2*n; i++)
          {          //打印预先安排座位
              if(!(i%50) && i)  cout<<endl;   
   	//50个字母一行
	if(j<table.size() && i==table[j])
	{//table留下的都是好人
                    j++; 
                    cout<<"G";
               }
              else   
                   cout<<"B";
          }
        cout<<endl<<endl;        //留一个空行
    }
    return 0;
}

Stack:基本的数据结构之一,特点是“先进后出”。

  • push(value)-将元素压栈
  • top()-返回栈顶元素的引用,但不移除
  • pop()-从栈中移除栈顶元素,但不返回
    操作
    实例:Text Reverse
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;  	
	char ch;
	scanf("%d",&n);  
	getchar();
	while(n--){
		stack<char> s;
		while(true){
		ch = getchar();                   //一次读入一个字符
	    	if(ch==' '||ch=='\n'||ch==EOF){
			while(!s.empty()){
				printf("%c",s.top());  //输出栈顶
				s.pop();                  //清除栈顶
			}
			if(ch=='\n'||ch==EOF)  break;
				printf(" ");
		}
		else   s.push(ch);                //入栈
			}
			printf("\n");
		}
	return 0;

实例:简单计算器

#include <stdio.h>
#include <stack>
#include <algorithm>
using namespace std;
int main()
{	
	double n,m;	
    char c;
	while(~scanf("%lf",&n))	
    { 
	      c=getchar();	
	      if(c=='\n' &&n==0)   break;
	      stack<double>s;
	      s.push(n);
	      scanf("%c",&c);
	      while(~scanf("%lf",&n))
	      { 
	            if(c=='*')
	            {
					m=s.top();
					m*=n;
					s.pop();
					s.push(m);
	            }
	           if(c=='/')
		 		{
					m=s.top();
					m/=n;
		 			s.pop();
		 			s.push(m);
     			}
	            if(c=='+')
				s.push(n);
            	if(c=='-')
					s.push(0-n);
            	if(getchar()=='\n') 
					break;
	            c=getchar();
      	  }
      	  double sum=0;
      	  while(!s.empty())
     	  {      
          		sum+=s.top();		
            	s.pop();
      	  }
      	  printf("%.2lf\n",sum);	
      	}
	return 0;
}

Queue:队列:基本的数据结构之一,特点是“先进先出”。

  • push(e)-将元素置入队列
  • front()-返回队列头部元素的引用,但不移除
  • back()-返回队列尾部元素的引用,但不移除
  • pop()-从队列中移除元素,但不返回
    在这里插入图片描述
    实例:ACboy needs your help again!
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t,n,temp;
    cin>>t;
    while(t--){
        string str,str1;
        queue<int>Q;
        stack<int>S;
        cin>>n>>str;
        for(int i=0; i<n; i++){
            if(str=="FIFO"){                  //队列
                cin>>str1;
                if(str1=="IN"){
                    cin>>temp;  Q.push(temp);
                }
                if(str1=="OUT"){
                    if(Q.empty()) 			         cout<<"None"<<endl;
                    else{
                        cout<<Q.front()<<endl;
                        Q.pop();
                    }
                }
            }
            else{                                //栈
                cin>>str1;
                if(str1=="IN"){
                    cin>>temp;  S.push(temp);
                }
                if(str1=="OUT"){
                    if(S.empty()) cout<<"None"<<endl;
                    else {
                        cout<<S.top()<<endl;
                        S.pop();
                    }
                }
            }
        }
    }
    return 0;
}

priority_queue(优先队列):以某种排序准则(默认为less)管理队列中的元素

  • push(e)-根据元素的优先级将元素置入队列
  • top()-返回优先队列头部最大的元素的引用,但不移除
  • pop()-从栈中移除最大元素,但不返回
  • empty() -队列是否为空

priority_queue <int,vector,less > p; //降序
priority_queue <int,vector,greater > q;//升序

实例:看病要排队
在这里插入图片描述

Deque:双端队列(deque模拟动态数组)

  • deque的元素可以是任意类型T,但必须具备赋值和拷贝能力(具有public拷贝构造函数和重载的赋值操作符)
  • 必须包含的头文件#include
  • deque支持随机存取
  • deque支持在头部和尾部存储数据
  • deque不支持capacity和reserve操作

构造、拷贝和折构
在这里插入图片描述
赋值操作
在这里插入图片描述
非变动操作
在这里插入图片描述
元素存取
在这里插入图片描述

List:双向链表。它的内存空间不必连续,通过指针来进行数据的访问,高效率地在任意地方删除和插入,插入和删除操作是常数时间。

list和vector的优缺点正好相反,它们的应用场景不同:
(1)vector:插入和删除操作少,随机访问元素频繁;
(2)list:插入和删除频繁,随机访问较少

  • push_back()
  • size()
  • max_size() 存放最多的元素的个数,只要内存足够,就能够一直分配
  • front() 返回第一个元素的引用,不检查元素是否存在
  • back() 返回最后一个元素的引用,不检查元素是否存在

插入元素
在这里插入图片描述
移出元素
在这里插入图片描述

迭代器(iterator):可遍历STL容器内全部或部分元素的对象;指出容器中的一个特定位置

双向迭代器
可以双向行进,以递增运算前进或以递减运算后退、可以用==和!=比较。list、set和map提供双向迭代器
随机存取迭代器
除了具备双向迭代器的所有属性,还具备随机访问能力。可以对迭代器增加或减少一个偏移量、处理迭代器之间的距离或者使用<和>之类的关系运算符比较两个迭代器。vector、deque和string提供随机存取迭代器stack、queue、priority_queuqe不支持迭代器

所有容器都提供两种迭代器:

  • container::iterator以“读/写”模式遍历元素
  • container::const_iterator以“只读”模式遍历元素

begin():返回一个迭代器,指向第一个元素
end():返回一个迭代器,指向最后一个元素之后

Set:set用二叉搜索树实现,集合中的每个元素只出现一次,且是排好序的。

在这里插入图片描述
在这里插入图片描述

Multiset:多重集合

  • 多重集合和set最大的区别就是,它可以插入重复的元素,
  • 如果删除的话,相同的也一起删除了;
  • 如果查找的话,返回该元素的迭代器的位置,若有相同,返回第一个元素的地址;

Map:使用平衡二叉树管理元素

  • 元素包含两部分(key,value),key和value可以是任意类型
  • 必须包含的头文件#include
  • 根据元素的key自动对元素排序,因此根据元素的key进行定位很快,但根据元素的value定位很慢
  • 不能直接改变元素的key,可以通过operator []直接存取元素值
  • map中不允许key相同的元素,multimap允许key相同的元素

其中map可以是下列形式
map<key,value> 一个以less(<)为排序准则的map,
map<key,value,op> 一个以op为排序准则的map
在这里插入图片描述
在这里插入图片描述
Map的赋值
第一种方式:
在这里插入图片描述
第二种方式:
在这里插入图片描述
第三种方式:
在这里插入图片描述

next_permutation(): 求“下一个”排列组合。

例如三个字符{a, b, c}组成的序列,next_permutation()能按字典序返回6个组合:abc,acb,bac,bca,cab,cba。

给定n个数字,从1到n,要求输出第m小的序列。
输入:数字n和m组成,1 <= n <= 1000,1 <= m <= 10000。
输出:输出第m小的序列。

#include<bits/stdc++.h>
using namespace std;
int a[1001];
int main(){
	int n, m;
	while(cin>>n>>m){
		for(int i=1; i<=n; i++)
                                a[i] = i;   //生成一个字典序最小的序列
		int b = 1;
		do{
		    if(b == m) break;
		    b++;
		}while(next_permutation(a+1,a+n+1));					 //注意第一个是a+1, 最后一个是a+n
              for(int i=1; i<n; i++)               //输出第m大的字典序
                      cout << a[i] << " ";
              cout << a[n] << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值