C++容器

206 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

C++ STL学习之vector

vector:变长数组(不固定大小的数组),类比于栈

ps:

​ 使用前要包含头文件 以及

​ #include:algorithm意为"算法",是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模版函数。

函数的调用: vector.对应函数名

​ size()//返回元素个数

​ empty()//返回是否为空;

​ clear()//清空元素,不清空内存​ front()//返回第一个元素的值

​ back()//返回最后一个元素的值​ push_back(x)//压入一个数x

​ pop_back()//弹出最后一个数​ begin()

​ end()

​ at()//取出下标

c_str()//执行 erase()//根据迭代器的位置,删除元素;erase(myvector.begin() + 3)

​ fill//填充

​ find

​ find_if

​ find_if_not

​ insert()插入元素;insert(myvector.begin() + 3, 998);//在第4个位置插入

​ sort()由小到大排序,用法见下文

​ swap()//交换两个vector

Iterators(迭代器)

​ 迭代器可被用来访问一个容器类的所包函的全部元素,其行为像一个指针。举一个例子,你可用一个迭代器来实现对vector容器中所含元素的遍历。

​ //正向迭代器iterator,begin()返回一个迭代器,它指向容器c的第一个元素,end()返回一个迭代器,它指向容器c的最后一个元素的下一个位置

​ //反向迭代器reverse_iterator,rbegin()返回一个逆序迭代器,它指向容器c的最后一个元素,rend()返回一个逆序迭代器,它指向容器c的第一个元素前面的位置

  vector<int>v;//相当于定义一个int类型的变长数组v
  //vector:变量类型,相当于string int double
  //<int>传入参数的类型,可以是float,double,string,int,Node...
  //v是变量名
  v.push_back(4);//压入一个值4
  v.push_back(2);
  v.push_back(8);
  ​
  
  vector<int>::iterator it;//定义一个类型为vector<int>的迭代器
      for(it =v1.begin();it l=vl.end();it++)
       cout<< *it <<endl;// * 代表取这个it对应的元素

[]的使用和数组一样

  
  v[0] = 1000;
  cout <<v[0]<<endl;
  是可以这样使用的,但是必须是先开辟了空间才能这样赋值,只定义了vector v就这样赋值时错误的!
  
  vector的初始化
  vector<int>abc(10);//初始化了10个默认值为0的元素
  
  sort(v.begin(),v.end());//由小到大排序

清空vector的内存

  
  /*C++中vector的clear()只是清空vector,并不会清空开的内存。用一种方法可以清空vector的内存。先定义一个空的vectorx,然后用需要清空的vector和x交换,因为x是局部变量,所以会被系统回收内存(注意大括号一定不能去掉)。*/
  vector<int> v;
  {
      vector<int>x;
      V. swap(x);
  }

实用案例

  
  //一、收缩内存
  vector<int>v;
  for(int i =0;i < 100000;i++)
  {
      v.push_back(i);
  }
  //此时v的大小是100000,v的容量是138255,因为vector容器会自动多开辟一些空间给你
  v.resize(3);
  //此时v的大小是3,v的容量是138255,造成了内存浪费
  vector<int>(v).swap(v);
  //这样就可以把v的多余内存释放掉,原理是利用拷贝构造初始匿名对象
  
  //二、巧用reverse预留空间
  如果要开辟大量空间那么系统就要不断地开辟新空间然后再进行存储转移,
  直接调用reserve(int类型要开辟空间的大小)就可以避免
  
  //逆序遍历可以直接调用反向迭代器
  for(vector<int>::reverse_iterator it = v.rbegin();it!=v.rend();it++)
  {
      cout<<*it<
  }

\

C++ set容器学习笔记

特点:

1.自动去重

2.升序排序

1.set容器的定义

  set<typename>name;//定义一个名字为name数据类型为typename的set容器
  typename:任意+STL(>>  加上空格)//数据类型可以是任意类型或者STL的其他容器

2.set容器的访问方式

迭代器(迭代器+整数vector string)

3.set容器的富用函数

insert() 时间复杂度logN,参数是typename类型,插入一个元素find() 时间复杂度log N,参数是typename类型,返回指向某个值的元素的迭代器

earse() 时间复杂度 1 //可以删除单个元素,也可以删除一定范围内的元素,删除单个元素用法和find一样,删除一定范围内的元素:one. erase (one. find(3), one. end());括号里面输入一个范围的迭代器

size() 求集合中有多少个元素,不用输入参数

clear() 时间复杂度 logN,清空所有元素,不用输入参数

get_allocator() 返回集合的分配器

key_comp() 返回一个用于元素间值比较的函数

value_comp() 返回一个用于比较元素间的值的函数

max_size() 返回集合能容纳的元素的最大限值

count(…) 返回某个值元素的个数 ——等价于find(…)//集合中一个元素最多出现一次,所以它的返回值 只有0和1

empty() 如果集合为空,返回true

4.set容器的用途

自动去重并且升序排序

C++ sort函数学习笔记

使用sort函数需要#include

也可以直接包含万能头文件#include<bits/stdc++.h>

同时要声明命名空间:using namespace std;

sort函数的基本用法

  sorta+ma+n);//[a+m,a+n)范围内的元素进行排序
  sorta+ma+ncmp);//cmp是函数或仿函数

想从大到小排序怎么办?

  
  /*原理是为真的时候,第一个数字放前面*/
  bool mycmp(int a,int b)
  {
      if(a>b)
      return 1;
      return 0;
  }
      
      int main()
      {
      int i;
      sort(a+0a+10,mycmp);//数组名+数字的本质是指针操作for(i=0i<10i++)
      printf("%d",a[i]);
          return 0;
      }

c++内置了两个比较大小的仿函数less<>,greater<>分别进行大小的比较。

less是从小到大排序,greater是从大到小排序

less和greater的参数都是要比较的数据的数据类型

对结构体进行排序

1、大小比较函数

2、重载运算符

3、仿函数

  
  struct node{
  int ab//重载“<”
  bool operator<(node B){
      ifa!=B.a)
          return a<B.a;
          return b<B.b;
  }

什么是友元函数?

在结构体里重载则排序的时候自动使用重载符号,在外面重载则要手动使用,

使用友元函数也可以在sort的时候自动使用。

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend

---------来自菜鸟教程 ## C++ map学习笔记

使用map得包含map类所在的头文件

#include

map时一个关联容器,提供一对一的映射关系。

  map<int,char>oneMap;

<key,value>

第一个称为关键字(key),别名时first,每个关键字只能在map中出现一次

第二个称为该关键字的值(value),别名是second。

用途

当数据结构具有对应关系的时候可以采用map

如”姓名-电话号码“

Alice 13824611111Bob13902382222Tom13002500333Jack 18011114444

就可以用map

  
  map< string,string>friends;
  friends. insert("Alice","13824611111"); 
  friends. insert("Bob","13902382222");
  friends. insert("Tom","13002500333");
  friends. insert("Jack","18011114444");

map对象创建的方式及函数

定义map对象:

  
  //map<key,value>mapName
  //key和value的类型可以是int、charstringlong、node等

插入对象(四种方式)

  
   oneMap. insert(pair<int, char>(1,'A')); 
   oneMap. insert(make_pair(2,'B'));//个人喜欢这个*
   oneMap. insert(map<int, char>:: value type(3,'C'));                              
   oneMap[4] = "D";
   //ps:当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值

迭代器函数

  //正向迭代器函数
  begin()//返回第一个元素的迭代器
  end()//返回最后一个元素的迭代器
  ​
      
  //反向迭代器函数    
  rbegin()//返回倒数第一个元素的迭代器
  rend()//返回倒数最后一个元素的迭代器

查找函数

  
  find(X)返回元素x的迭代器,为空则返回map::end()位置
  oneMap.find(1);或者oneMap.find('A');

clear()和empty()

  
  oneMap.clear();
      if(oneMap.empty())
      {
          cout<<"容器为空”<<end1;
      }
      else
      {
          cout<<"容器不为空”<<end1;
      }

equal_range(x)

  
  返回元素X的迭代器;X指的是关键字
  cout<<*oneMap.equal_range(2).first).first//输出关键字为2的迭代器的关键字
  <<"->"<<oneMap.equal_range(2).first->second//输出关键字为2的迭代器的数值
  <<end1;
  //输出结果:2->'B'

equal_range.firstlower_bound返回值是一样的,都是指向第一个相等元素(可以这样认为)的迭代器,无论最后找到或者找不到匹配的关键字,它们都相等。

同理,equal_range.secondupper_bound的返回值一样,都是指向最后一个相等元素的后一个元素的迭代器,如果找不到关键字,那么将会得到一个安全的关键字插入位置。

容量

  
  //size()   max_size()
  cout<<"当前大小为:"<<oneMap.size()<<end1;cout<<"最大容量为:"<<oneMap.max_size()<<end1;
  //size()返回当前容器的大小,max_size返回当前容器最大容量

交换两个map

  
  swap();参数是map类型