C++与STL入门

C++ 标准模板库的核心包括以下三个组件:

组件 描述
容器(Containers) 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
算法(Algorithms) 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。
迭代器(iterators) 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
这三个组件都带有丰富的预定义函数,帮助我们通过简单的方式处理复杂的任务。

本文简要介绍:

  1. vector
  2. set
  3. list
  4. queue
  5. map

不定长数组:vector

vector是一个模板类,所以需要用vector<int>a或者vector<double>b来声明一个vector。vector<int>是一个类似于int a[]的整数数组,而vector<string>就是一个类似于string a[]的字符串数组。
**相比于数组的优势:**可以直接赋值,还可以作为函数的参数或者返回值,而无需像传递数组那样另外用一个变量指定元素个数。

vector的使用:

要想用vector首先得包含头文件vector
#include <vector>
初始化,T为任意变量类型

常用操作:

#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <typename T> //定义一个模板 
void showvector(vector<T> v)// 使用迭代器 iterator 访问值
{
    for (vector<T>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main(int argc, char const *argv[])
{
	vector<int>a;//初始化vector 
	for(int i = 0; i < 5; i++){ //插入5个顺序元素 
      a.push_back(i);//向尾部插入 
    }
	cout<<a.size()<<endl;//输出vector长度
	   
   for(int i = 0; i < a.size(); i++){// 访问向量中的 5 个值
      cout << "value of vec [" << i << "] = " << a[i] << endl;
   } 
   
   cout<<a.size()<<endl;//输出vector的长度 
   a.resize(4);//修改长度 

   cout<<a[4] <<endl;//虽然长度变了,但是之前存入的值还是能被访问到
   a.pop_back(); //删除最后一个元素
   
   a.insert(a.begin()+1,9); //在第二个位置插入新元素
   a.insert(a.begin() + 1, 8,8); //连续插入8个8
   a.erase(a.begin() + 3);  //删除第四个元素
   a.erase(a.begin(),a.begin()+3); //连续删除3个元素 
	for(int i = 0; i < a.size(); i++){// 访问向量中的 5 个值
	  cout << "value of vec [" << i << "] = " << a[i] << endl;
	} 
   a.clear(); //清除所有内容
}

集合set

set就是数学上的集合—每个元素最多只出现一次。set里面的元素是有序的且唯一的,只要你往set里添加元素,它就会自动排序,而且,如果你添加的元素set里面本来就存在,那么这次添加操作就不执行。和sort一样,自定义类型也可以构造set,但同样必须定义“小于”运算符

  1. 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素

  2. 不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数

  3. 元素比较动作只能用于型别相同的容器(即元素和排序准则必须相同)

#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

void showset(set<string> &v)
{
    for (set<string>::iterator it = v.begin(); it != v.end(); it++)
        cout << *it<<endl;
}

int main()
{
	set<string> s;
	s.insert("sfsf");//往set里面添加元素 
	s.insert("abb");
	s.insert("cds");
	s.erase(s.begin());//删除,注意不同于vector,只能一个个删除 
	s.erase("sfsf");//或者删除指定元素 
	showset(s);
    
    
    return 0;
} 

链表list

list是一个双向链表,而单链表对应的容器则是foward_list。
list即双向链表的优点是插入和删除元素都比较快捷,缺点是不能随机访问元素

值得注意的是,list容器不能调用algorithm下的sort函数进行排序,因为sort函数要求容器必须可以随机存储,而list做不到。所以,list自己做了一个自己用的排序函数。

list<int> l1{ 8,5,7,6,1,2,3,4,5,5,6,7,7 };
l1.sort();

声明一个int型的list:list a;

1、list的构造函数

lista{1,2,3}
lista(n) //声明一个n个元素的列表,每个元素都是0
lista(n, m) //声明一个n个元素的列表,每个元素都是m
lista(first, last) //声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素,first和last是迭代器

2、begin()和end()
通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator,可以调用list容器的end()函数来得到list末端下一位置

3、push_back()和push_front()

使用list的成员函数push_back和push_front插入一个元素到list中。其中push_back()是从list的末端插入,而push_front()是从list的头部插入。

4、empty()

判断list是否为空

5、resize()

调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除。如果n比list原来的长度长,那么默认超出的部分元素置为0。也可以用resize(n, m)的方式将超出的部分赋值为m。

例子:

listb{1, 2, 3, 4};
b.resize(2);
list中输出元素:1,2
listb{1, 2, 3, 4};
b.resize(6);
list中输出元素:1,2,3,4,0,0
listb{1, 2, 3, 4};
b.resize(6,9);
list中输出元素:1,2,3,4,9,9

6、clear()

清空list中的所有元素

7、front()和back()

通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。注意:当list元素为空时,这时候调用front()和back()不会报错。因此在编写程序时,最好先调用empty()函数判断list是否为空,再调用front()和back()函数。

8、pop_back()和pop_front()

使用pop_back()可以删掉尾部第一个元素,pop_front()可以删掉头部第一个元素。注意:list必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。

9、assign()

有两种使用情况:

(1)a.assign(n, val):将a中的所有元素替换成n个val元素

例如:

listb{1,2,3,4,5};
b.assign(5,10);
b中的元素变为10, 10, 10, 10, 10

(2)a.assign(b.begin(), b.end())

lista{6,7,8,9};
listb{1,2,3,4,5};
b.assign(a.begin(),a.end());
b中的元素变为6,7,8,9

10、swap()

交换两个链表。a.swap(b)和swap(a, b),都可以完成a链表和b链表的交换。

例子:

lista{6,7,8,9};
listb{1,2,3,4,5};
swap(a, b); //或a.swap(b)
a中元素变为1,2,3,4,5

b中元素变为6,7,8,9

11、reverse()

可以实现list的逆置

例子:

listb{1,2,3,4,5};
reverse(b.begin(),b.end());
b中元素变为5,4,3,2,1

12、merge()

a.merge(b) 调用结束后b变为空,a中元素包含原来a和b的元素。

例子:

lista{6,7,8,9};
listb{2, 1, 3, 6, 5};
a.merge(b,greater());
a中元素变为:6,7,8,9,2,1,3,6,5

lista{6,7,8,9};
listb{2, 1, 3, 6, 5};
a.merge(b);
a中元素变为:2,1,3,6,5,6,7,8,9

13、insert()

在指定位置插入一个或多个元素

a.insert(a.begin(),100); //在a的开始位置(即头部)插入100
a.insert(a.begin(),2, 100); //在a的开始位置插入2个100
a.insert(a.begin(),b.begin(), b.end());//在a的开始位置插入b从开始到结束的所有位置的元素

14、erase()
删除一个元素或一个区域的元素

a.erase(a.begin()); //将a的第一个元素删除
a.erase(a.begin(),a.end()); //将a的从begin()到end()之间的元素删除。

15、remove()函数

从list中删除元素

lista{6,7,8,9,7,10};
a.remove(7);
删除了a中所有值为7的元素,此时a中元素为6,8,9,10

queue

queue 模板类的定义在头文件中。
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
定义queue 对象的示例代码如下:
queue q1;
queue q2;

queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()

#include <cstdlib>
#include <iostream>
#include <queue>
  
using namespace std;
  
int main()
{
    int e,n,m;
    queue<int> q1;
    for(int i=0;i<10;i++)
       q1.push(i); //向队尾插入元素
    if(!q1.empty()) cout<<"queue is not empty";//判断是否为空
    n=q1.size();//返回队列内元素的数目
    cout<<n<<endl;
    m=q1.back();//访问队尾元素
    cout<<m<<endl;
    for(int j=0;j<n;j++)
    {
       e=q1.front();//访问队首元素
       cout<<e<<" ";
       q1.pop();//弹出队首元素
    }
    return 0;
}

map

map运用了哈希表地址映射的思想,也就是key-value的思想,来实现的。

声明
例:

map<string,int>;//声明一个key为string,value为int的map

常用函数
clear
清除 map 中所有元素;
erase
删除 map 中指定位置的元素;
insert
在 map 指定位置添加 pair 类型的元素;
find
获取 map 中元素的迭代器;
begin, end
map 的正向迭代器的起始位置与终点位置;
rbegin, rend

    // 1. 直接定义
    map<char,int> mymap;
    mymap['a'] = 10;
   // 2. 复制
    map<char, int> second(mymap);
    //修改值
    second['a']=1002;
    //使用insert函数插入
    mymap.insert(pair<char,int>('f',100) );

本文主要参考:

  1. 《算法竞赛入门经典(第二版)》
  2. C++ STL快速入门
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值