首页 > 编程语言 >STL容器和算法

STL容器和算法

时间:2023-08-20 17:34:50浏览次数:75  
标签:容器 迭代 10 STL elem v1 算法 vector

目录

STL容器和算法

基本概念

标准模板库,主要分为容器、算法、迭代器。

通过迭代器访问容器中的数据,并进行算法操作。

所有代码采用模板类和模板函数的方式。

容器

容器的分类

序列式容器

每个元素都有固定位置,该位置取决于插入时机和地点,和元素值无关。

vector,deque,list,stack,queue

关联式容器

元素位置取决于特定的排序准则,和插入顺序无关。

set multiset map multimap

vector容器

连续存储的动态数组,类似于数组,不过是动态的,可以添加移除元素。

尾部添加移除元素方便,但是中部或头部比较麻烦,复杂度为O(n)。

vector的定义

//无参构造
vector<int> int1darray;
vector<vector<int>> int2darray;

//带参数构造
vector(start, end);//左闭右开[start,end)
vector(n, elem);//拷贝n个elem
vector(const vector &vec);//拷贝构造函数

比如:
int arr[5] = {0};
vector<int> int1darray1(arr,arr+5);//拷贝arr
vector<int> int1darray2(3, 10);//存储3个10

vector<int> int1darray3(int1darray1);//拷贝int1darray1

vector的赋值

vector.assign(beg,end);//将[beg,end)区间的数据拷贝给本身
vector.assign(n,elem);//将n个elem拷贝赋值给本身
vector &operator=(consr vector &vec);//重载等号操作符
vector.swap(vec);将vec与本身元素交换

比如:
vector<int> v1,v2,v3,v4;
int array[] = {1,2,3,4,5};
v1.assign(array,array+5);
v2.assign(3,10);
v3 = v2;
v4.swap(v3);

vector的大小

vector.size();//容器元素的个数
vector.empty();//判断容器是否为空
vector.resize(num);//重新指定容器长度为num,多余删除,不够添加默认值
vector.resize(num,elem);//重新指定容器长度为num,多余删除,不够添加elem

比如:
vector<int> v1(3,10);

v1.size();//3
v1.empty();//False
v1.resize(5);//10,10,10,0,0
v1.resize(5,3);//10,10,10,3,3

vector的访问方式

[]下标法和.at(idx)
但是[]下标法的下标有时候会越界,导致程序异常终止,但不会抛出异常信息,和数组同理。

采用.at(idx),如果出现越界情况,抛出异常信息out_of_range。

vector的元素操作

//在末尾插入移除元素
vector.push_back(elem);//末尾插入
vector.pop_back(elem);//末尾删除
// 可在任意位置插入删除,但是复杂度不同

注意pos必须是指针(v1.begin())
vector.insert(pos,elem);//在pos位置插入一个elem的拷贝,返回新数据的位置
vector.insert(pos,n,elem);//在pos位置插入n个elem的拷贝,无返回
vector.insert(pos,beg,end);//在pos位置插入[beg,end)的数据,无返回


比如:
vector<int> v1(3,10);//10,10,10
v1.insert(v1.begin()+2,3);//10,10,3,10 返回2
v1.insert(v1.begin()+2,2,4);//10,10,4,4,3,10
int array[] = {1,2,3};
v1.insert(v1.beign()+2,array,array+3);//10,10,1,2,3,4,4,3,10

deque容器

double-ended queue。

deque是双端数组,而vector是单端数组。deque的许多操作和vector相似。

单端:长度可以沿着一个方向变化 O(n)
双端:长度可以沿着两个方向变化

deque头部和尾部添加移除元素很快,但是中部比较麻烦。

#include <deque>

deque.push_front(elem);//头部添加
deque.pop_front();//头部删除

deque<int> d1 = {1,2,3,4};
d1.push_front(5);//5,1,2,3,4
d1.pop_front();//1,2,3,4

list容器

基本概念

迭代器

基本概念

迭代器是一种检查容器内元素并且遍历容器内元素的数据类型

常用于提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。

统一了对所有容器的访问方式,提高编程效率。

vector的迭代器

//定义vector迭代器对象
vector<int>::iterator iter;

vector<int> v1(3,10);
v1.begin();//返回指向容器的第一个元素的正向迭代器
v1.end();//返回指向容器最后元素的下一个位置的正向迭代器


//迭代器指向第一个元素
vector<int> v1(3,10);
iter = v1.begin();

//使用迭代器遍历容器
for(iter = v1.begin();iter != v1.end();iter++)
	cout<< *it << " ";

注意:iter++可以实现的原因是迭代器本身实现了++运算符的重载,* 同理。

迭代器失效

//插入元素失效
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);

vector<int>::iterator it = v.begin() + 3;
v.insert(it, 8);
cout<<*it<<endl;//输出0或4

/*
编译器在插入元素时,会新new一个内存空间再把原来的容器拷贝过去。
那么针对之前的空间,不同编译器处理的方式也不同,有些是保持不动,有些覆盖为0。
而it迭代器依然指向原来的内存空间,所以输出有可能是4或0。这就是迭代器失效(变成了野指针)。
解决办法;
insert函数会返回新的迭代器或采用深拷贝。
*/
//删除元素失效

vector<int> v1 =  {1,2,3,3,3,4};
vector<int>::iterator it;

for(it = v1.begin();it != v1.end();it++)
{
	if(*it == 3)
	v1.erase(it);
}
for(it = v1.begin();it != v1.end();it++)
{
	cout<< *it << " ";//输出1,2,3,4
}
/*
删除是覆盖的操作,并且删除之后it会向前移动,导致遗漏。
*/

修改之后;
for(it = v1.begin();it != v1.end();)
{
	if(*it == 3)
		v1.erase(it);
	else
		it++;
}
或者使用erase函数返回的新迭代器

总结:在使用迭代器进行插入或删除的操作时,需要对迭代器重新赋值以保证迭代器一直有效。

算法

标签:容器,迭代,10,STL,elem,v1,算法,vector
From: https://www.cnblogs.com/z-qhhh/p/17643969.html

相关文章

  • 算法总结
    前言:有关于算法的一切的大合集基本数据结构及排序方法手撸完全二叉树/满二叉树红黑树节点分为红色或者黑色;根节点必为黑色;叶子节点都为黑色,且为null;连接红色节点的两个子节点都为黑色(红黑树不会出现相邻的红色节点);从任意节点出发,到其每个叶子节点的路径中包含相同数......
  • 快速幂算法
    快速幂洛谷P1226【模板】快速幂||取余运算#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;llquickpow(lla,llb,llp=10){ //计算a的b次方 if(b==0)return1; intans=1; while(b){ if(b&1){ ans=ans*a%p; } ......
  • 第二十三节 API(算法,lambda,练习)
    常见的七种查找算法:​ 数据结构是数据存储的方式,算法是数据计算的方式。所以在开发中,算法和数据结构息息相关。今天的讲义中会涉及部分数据结构的专业名词,如果各位铁粉有疑惑,可以先看一下哥们后面录制的数据结构,再回头看算法。1.基本查找​ 也叫做顺序查找​说明:顺序......
  • UFCFT4-15-3 加密系统算法
    MODULARPROGRAMMECOURSEWORKASSESSMENTSPECIFICATIONModuleDetailsModuleCodeUFCFT4-15-3 Runsem3FIRSTSIT2023/24 ModuleTitleCryptographyModuleLeader ModuleTutorsSMLAUComponentandElementNumberProgram(includingsourcecodeandexecutable)and......
  • 基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护
    基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护传输数据-编码型&加密型等传输格式-常规&JSON&XML等密码存储-Web&系统&三方应用代码混淆-源代码加密&逆向保护加密:1.常见加密编码进制等算法解......
  • 探索编程世界的宝藏:程序员必掌握的20大算法
    #程序员必须掌握哪些算法?#1引言在当今数字化时代,程序员们仍然需要拥有一把解决问题和优化代码的金钥匙。这些钥匙是算法,它们隐藏在计算机科学的宝藏中,等待着我们去发现和掌握。本篇博文将带你踏上一段引人入胜的探险之旅,揭开程序员必须掌握的20大算法的神秘面纱。从冒泡排序到......
  • Docker容器操作
    1dockerexec这个命令dockerexec是对运行状态的容器进行执行一个命令,exec就是execute的简写,单词就是执行的意思。例如我们基本上容器都是说linux环境下的容器,在linux下我们经常做的事情就是要执行各种shell命令,所以这个命令用到最多的场景是执行一个容器下的bash程序,然后输入一个......
  • c++算法之动态规划:01背包
    什么是动态规划?动态规划算法(dynamicprograming),是一种由递推为基础的比贪心更稳定的一种优化策略,为运筹学的一部分。就是通过以递推为基础的手段非暴力求出最值。它的总体思想其实就是一个比较过程:假如你有一个数据,它的价值是x,代价为y,如果用动态规划就是和你不加这个元素和你加......
  • 欧几里得算法(辗转相除法)-- 实现分数计算
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-"""利用欧几里得算法实现一个分数类,支持分数的四则运算(加法)"""classFraction:def__init__(self,a,b):self.a=aself.b=bx=self.gcd(a,b)se......
  • *【学习笔记】(23) 常用距离算法详解
    本文主要讲述这三种常见距离算法:欧氏距离,曼哈顿距离,切比雪夫距离。1.欧氏距离欧氏距离是最易于理解的一种距离算法。在数学的平面直角坐标系中,设点\(A,B\)的坐标分别为\(A(x_1,y_1),B(x_2,y_2)\),求点\(A,B\)之间的距离,我们一般会使用如下公式:\[\left|AB\right|=......