CSP语法基础题(五)

CSP语法基础课(五)-容器STL

  1. vector

    vector是一个可以自动改变长度的数组

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main(){
      vector<int> a;	//定义一个vector数组
      vector<int> [100];	//定义100个vector,每一个都是长度动态变化的vector
      
      //所有的STL基本都有这俩函数
      a.size();
      a.empty();	//返回bool值
      
      a.clear();
      //迭代器定义iterator,就是C语言中的指针
      vector<int> ::iterator it = a.begin();
      //	类似指针it+2访问的就是a[2]
      cout << *it << " "<< *(it+2);
      *a.end();		//是最后一个元素的下一地址	效果等同于a[0]
      *a.begin();		//是第一个元素的地址			效果等同于a[a.size()-1]
      
      //初始化一个vector
       vector<int> z({1,2,3});
       cout << *z.begin() << "==" << z[0] << endl;
      //所有容器都可以看做一个左闭右开的结构
      
      //遍历方式一:数组一样
      for(int i=0;i<z.size();i++)	cout <<z[i]<<endl;
      //遍历方式二:迭代器					为了方便使用auto会非常方便
      for(auto i=z.begin();i!=z.end();i++) cout << *i << endl;
      for(vector<int>::itrator i =z.begin();i!=z.end();i++)	cout<<*i<<endl;
      //遍历方式三:范围遍历	
      for(int c:a)	cout << c << endl;
      
      
      //front\back返回的是元素	back和迭代器end返回的略有不同,back返回的是最后一个元素
      cout<< z.front() << " = " << *z.begin() << " = " << z[0] <<endl;
      cout<< z.back()  << " = " << *(z.end()-1)   << " = " << z[z.size()-1] <<endl;
      
      //push_back()数组的末尾添加元素 //pop_back()····而且这俩个函数对应的操作都是O(1)时间复杂度
      	z.push_back(4);
      	z.pop_back();		//删除最后一个元素
      
      // 也可以定义结构体vector
      struct Rec{
        int x,y;
      }
      vector<Rec> c;
      return 0;
    }
    

vector实现原理:vector数组动态增长采用的是倍增技术。

  1. queue

    主要包括循环队列queue优先队列priority_queue两个队列

#include<iostream>
#include<queue>

using namespace std;

int main(){
  queue<int> q1;
  queue<double> q2;
  struct Rec{
    int x,y;
    double a,b;
  }
  queue<Rec> s[100]	//和vector一样,这样定义其实也是一个二维空间,列表个数是100个,每个都是一个列表
    
    //队列的性质 先进先出
    
  
  return 0;
}

priority_queue 优先队列。一般默认的是每次弹出的是最大的元素

#include<iostream>
#include<queue>
#include<vector>
using namespace std;

int main(){
  queue<int> q;
  
  q.push(1);		//队尾插入
  q.pop();			//队头弹出
  q.front();		//返回队头元素
  q.back();			//返回队尾元素
  
  
  
  //大根堆
  priority_queue<int> a;	//定义一个大根堆
  priority_queue<int,vector<int>,greater<int>> b;	//定义小根堆,每次弹出最小值
  
  a.push(1);	//给队列插入元素
  a.top();	//取出队列的最大值
  a.pop();	//删除最大值
  
  //自定义结构体放入优先队列的时候,要对小于号进行重载
  struct Rec{
    int x,y;
    //这里要对小于号进行重载
  };
  priority_queue<Rec> a;
  
}

PS:队列、优先队列、栈没有clear()函数;

  1. stack

头文件include,包含栈.

和队列比较像,好多函数也是一样。先进后出罢了。

#include<stack>

using namespace std;

int main(){
  
  stack<int> a;
  a.push(1);
  a.push(2);
  a.pop();
  a.pop();
  return 0;
}
  1. 双端队列deque

    两边都可以插入、删除的队列。优点像vector和queue的结合。与queue相比,deque支持随机访问;与vector相比,deque支持在头部增删元素O(1)

#include<deque>

deque<int> q;	//定义
q.begin(),q.end();	//返回q的头尾迭代器
q.front(),q.back();	//直接返回头尾元素
q.push_back(1);//在deque最后插入一个元素
q.push_front(1);	//在deque开头插入一个元素
q[i];				//支持随机访问

q.pop_back();	//删除最后一个元素
q.pop_front();	//删除第一个元素

q.clear();	//清空deque
  1. set

    #include<set>
    //	包含两种set和multiset
    set<int> a;	//不能包含重复元素,如果插入重复元素,会忽略掉这个元素
    multiset<int> b;	//元素可以重复 
    	//两种set实现基本相同,函数也是基本相同
    
    //	也可以自己定义set元素类型
    struct Rec{
      int x,y;
      //这里还是需要重载小于号,因为set里的元素还是要做比较的
    };
    set<Rec> new_a;
    set<int> ::iterator it = a.begin();
    it++;			//迭代器加加表示有序序列的下一个元素
    
    
    size/clear/empty也有
    
    //插入一个元素
    a.insert(x);
    //查找一个元素,会返回值等于x的一个迭代器;要是没有x,则会返回a.end()的迭代器
    a.find(x);
    //查找一个大于等于元素x的最小元素的迭代器
    a.lower_bound();
    //查找一个大于元素x的最小元素的迭代器,这里之前理解错了,这里不是字面意思
    a.upper_bound();
    //查找元素x在a中出现的个数			,set的话返回的是0或者1
    a.count(x);		
    //删除集合中值等于x的所有元素
    a.erase(x);
    
    
  2. map

#include<map>

using namespace std;
int main(){
  map<int,int> a;
  a[1] = 2;	//存键值对1-2
  a[10000] = 8;	//存键值对10000-8
  //当定义两个都是int型的时候,有点像是数组
  
  map<string,int> b;
  b["liufeng"] = 200;
  b["wife"]    = 2000;
  cout << b["liufeng"] << endl;		//输出的就是200
  
  map<string,vector<int>> c;
  c["liufeng"] = vector<int>({1,2,3});
  cout << c["liufeng"][2] << endl;	//输出的应该就是3
  
  c.insert({"liufeng",{1,2,3}});	//除了上面赋值形式的插入,也可以使用insert函数
  return 0;
}
  1. unordered_set 无序set PS:只有在C++11里面才支持unordered_set和unordered_map

    #include <unordered_set>
    
    int main(){
      unorder_set <int> a;	/*和set非常相像,但是没有lower_bound和upper_bound这两个函数(因为是无序的啊)	其余所有函数都是存在的,而且操作的效率是O(1),set数据操作的时间复杂度是
    O(n) ,所以unorder_set的效率是比较高的。低层实现使用的哈希表。 */
      unorder_multiset<int> b;	//也是一个哈希表,顾名思义,集合的元素是可以重复的
      
      
    }
    
  2. unordered_map 时间效率也是比较高是,O(1)的,map的时间复杂度就比较低了是O(n),同样的也不支持二分

#include <unordered_map>

int main(){
  unordered_map <int,int> b;		//unordered_map也是操作效率比较高,各种查询操作的时间复杂度都是O(1)的,坏处是不支持二分
}
  1. bitset 这个是定义一个非常长的二进制串
#include <bitset>

using namespace std;
int main(){
  bitset<1000> a;		//括号里面写串的长度,定义了一个长度是1000位的01串
  a[0] =1;
  cout << a[0] << endl;
  cout << a[1] << endl;		//没有赋值的应该是0
  
  a.count();	//返回里面1的个数
  
  //也可以进行位运算& | 
  bitset<1000> b;
  a &=b;
  a |=b;
  
  //set函数,可以把第几位设置成1
  b.set(3);
  b.set(4);
  b.set(5);
  cout << b[3] << b[4] << b[5] << endl;
  
  b.reset(3);
  b.reset(4);	//把第4位设成0
  b.reset(5);	//把第5位设成0
  return 0;
}

pair

pair<int,string> a;		//pair和vector自带比较运算 支持 > 、<、==、!=、
a = {100,"liufeng"};

//c++99里面,pair只能使用make_pair来赋值
a = make_pair(4,"abc");


cout << a.first  << " " << a.second << endl;
posted @ 2021-03-10 23:00  _Sandman  阅读(81)  评论(0编辑  收藏  举报