【P186 20】C++ 容器快速入门 (vector、deque、list、map、set...)(超详细)

2023-11-01

P186 20

vector指向量,可以理解为“变长数组”,长度根据需要而自动改变的数组。有时会碰到普通数组会超过内存的情况,可以使用vector解决。
而且,vector可以用来以邻接表的方式存储图,可以解决当节点数太多,无法使用邻接矩阵,又害怕使用指针实现邻接表的时候,使用很简单。
在这里插入图片描述

一、vector容器

vector是一种类模板,是一种顺序容器。顺序容器是按照是按照元素在标准库里边的顺序保存和访问的。

1.vector存放内置数据类型

在这里插入图片描述

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

//vector存放内置数据类型
void test01()
{
	//创建一个vector容器,(数组)
	vector<int> v;
	
	//向容器中插入数据
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
}

int main()
{
	test01();
	return 0;
}

1.六种遍历方式

六种遍历方式,完整代码总览

//遍历方式1,采用迭代器
for (vector::iterator it = vec.begin(); it != ovec.end(); it++)
{
cout <<  *it  << endl;
}
//遍历方式2,采用迭代器.并采用C++11新标准中的auto关键字
for (auto it = vec.begin(); it != vec.end();it++)
{
cout <<  *it  << endl;
}
//遍历方式3,while (itBegin != itEnd)
while (itBegin != itEnd)
{
	cout << *itBegin << endl;
	itBegin++;
}
//遍历方式4,采用下标进行数据元素访问
for (size_t i = 0; i < vec.size(); i++)
{
cout << vec[i]<< endl
}

//遍历方式5,采用C++11新标准中的auto关键字
for (auto i:vec)
{
cout << i<< endl;
}

//第6种遍历 利用STL提供的算法
	for_each(v.begin(), v.end(), myPrint);

部分遍历详解

第一种遍历方式

//通过迭代器访问容器中的数据
vector<int>::iterator itBegin = v.begin();//起始迭代器 指向容器中第一个元素
vector<int>::iterator itEnd = v.end();//    结束迭代器 指向容器中做后一个元素的下一个位置
//第一种遍历方式
while (itBegin != itEnd)
{
	cout << *itBegin << endl;
	itBegin++;
}

在这里插入图片描述

在这里插入图片描述

第二种遍历方式

//第二种遍历方式
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	cout << *it << endl;

第三种遍历 利用STL提供的算法

遍历前需要
1.添加头文件#include//标准算法的头文件
2.添加一个打印函数

void myPrint(int val)
{
	cout << val << endl;
}
//第三种遍历 利用STL提供的算法
for_each(v.begin(), v.end(), myPrint);

2 初始化,区别

1 默认初始化,无参(没给定数组大小)

 vector<int> res;; 默认初始化

vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。
这种初始化方式适用于元素个数未知,需要在程序中动态添加的情况;

添加元素,只能用.push_back();

for (int i = 10; i < 18; i++)
	res.push_back(i);

以下下错误,因为还没有分配内存空间。

for (int i = 10; i < 18; i++)
	res[i] = i;

2 带参数构造初始化 (给定数组大小、初始值)

vector<int> res(8);

res中将包含8个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0,因此res被初始化为包含8个0。

等同于

vector<int> res(8,0);

指定值初始化,ilist5被初始化为包含7个值为3的int。

vector<int> ilist5(7,3);

添加元素,可用res[i] = a;也可.push_back(a);

for (int i = 0; i < 8; i++)
	res.push_back(i);
for (int i = 0; i < 8; i++)
	res[i] = i;

但是,res[i] = a;这种数组下标只允许在数组长度以内,比如本例0~8;
下面for循环0~10越界,11 ~13,起点都不在范围内,都会报错;

for (int i = 0; i < 10; i++)  res[i] = i;
for (int i = 11; i < 15; i++)  res[i] = i;

而对于 res.push_back(a);没有限制的,因为他是在前面定长数组尾部动态追加的;

for (int i = 0; i < 8; i++)  res.push_back(i);

3. 1 2 两种初始化特点对比测试

//定义数组
	vector<int> res(8);
	cout << "res.size() = " << res.size() << endl;
	//给数组重新赋值
	for (int i = 0; i < 8; i++)
		res[i] = i;
	//输出
	for (int i = 0; i < res.size(); i++)
		cout << res[i] << endl;
	cout << "res.size() = " << res.size() << endl;

在这里插入图片描述

//定义数组
	vector<int> res(8);
	cout << "res.size() = " << res.size() << endl;
	//给数组重新赋值
	for (int i = 0; i < 8; i++)
		res.push_back(i);
	//输出
	for (int i = 0; i < res.size(); i++)
		cout << res[i] << endl;
	cout << "res.size() = " << res.size() << endl;

在这里插入图片描述

4 通过同类型的vector进行初始化

vector<int> ilist2(ilist); 
vector<int> ilist2  = ilist;

这两种方式等价 ,ilist2 初始化为ilist的拷贝,ilist必须与ilist2 类型相同,也就是同为int的vector类型,ilist2将具有和ilist相同的容量和元素。

5.通过迭代器进行初始化

vector<int> ilist3(ilist.begin()+2,ilist.end()-1);

ilist3初始化为两个迭代器指定范围中元素的拷贝,范围中的元素类型必须与ilist3 的元素类型相容,在本例中ilist3被初始化为{3,4,5,6}`。

这种初始化方法特别适合于获取一个序列的子序列。

6 .带参数构造初始化

vector<int> ilist5(7,3);

指定值初始化,ilist5被初始化为包含7个值为3的int。

7 通过数组地址初始化

int a[5]={1,2,3,4,5}
vector<int> vec_i(a,a+5);

8 直接用{ }初始化

vector<int> vec={1,2,3,4,5,6,7,8,9}

9 初始为二维数组

vector<vector<int>> arr(8,vector<int>(8,0));

8*8的二维数组,元素都是0;

3.vector存放自定义的数据类型

1.自定义数据类型

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

//vector存放自定义数据类型
class Person 
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};

void test01()
{
	//创建一个vector容器,(数组)
	vector<Person> v;
	Person p1("a",10);
	Person p2("b", 20);
	Person p3("c", 30);
	Person p4("d", 40);

	//向容器中插入数据
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);

	//遍历容器中的数据
	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
		//cout << "姓名:" <<(*it).m_Name <<"    年龄:"<<(*it).m_Age<< endl;
	      cout << "姓名:" << it->m_Name << "    年龄:" << it->m_Age << endl;

}

int main()
{
	test01();
	return 0;
}

在这里插入图片描述

//遍历容器中的数据
//两种输出方式
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	//cout << "姓名:" <<(*it).m_Name <<"    年龄:"<<(*it).m_Age<< endl;
      cout << "姓名:" << it->m_Name << "    年龄:" << it->m_Age << endl;

2.自定义数据类型 指针

test()中稍加修改,其他不变

void test02()
{
	//创建一个vector容器,(数组)
	vector<Person *> v;//Person*
	Person p1("a", 10);
	Person p2("b", 20);
	Person p3("c", 30);
	Person p4("d", 40);

	//向容器中插入数据
	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);
	v.push_back(&p4);

	//遍历容器中的数据
	for (vector<Person *>::iterator it = v.begin(); it != v.end(); it++)
		 cout << "姓名:" <<(*it)->m_Name <<"    年龄:"<<(*it)->m_Age<< endl;
}

在这里插入图片描述

4.vector容器嵌套容器

学习目标:容器中嵌套容器,我们将所有数据进行遍历输出

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

//容器嵌套容器
void test02()
{
	vector<vector<int>>v;

	//创建小容器
	vector<int>v1;
	vector<int>v2;
	vector<int>v3;
	vector<int>v4;
	vector<int>v5;

   //向小容器中插入数据
	for (int i = 0; i < 5; i++)
	{
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
		v4.push_back(i + 4);
		v5.push_back(i + 5);
	}
	
   //将小容器插入到大容器中
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);
	v.push_back(v5);


   //通过大容器,把所有数据遍历一遍
	for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
	{
		//(*it)-----容器 vector<int>
		for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
		{
			cout << *vit << " ";
		}
		cout << endl;
	}

}
int main()
{
	test02();
	return 0;
}

在这里插入图片描述

二、string容器

1.string基本概念

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

2.string构造函数

构造函数原型

-string();					//创建一个空的字符串例如:string str;
 string(const char* s);		//使用字符串s初始化
-string(const string& str);	//使用一个string对象初始化另一个string对象
-string(int n, char c);		//使用n个字符c初始化

程序

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

//string的构造函数

/*
-string();					//创建一个空的字符串例如:string str;
 string(const char* s);		//使用字符串s初始化
-string(const string& str);	//使用一个string对象初始化另一个string对象
-string(int n, char c);		//使用n个字符c初始化
*/
void test02()
{
	string s1;//默认构造

	const char* str = "hello world";
	string s2(str);
	cout << "s2=" << s2 << endl;

	string s3(s2);
	cout << "s3=" << s3 << endl;

	string s4(10,'a');//10个a
	cout << "s4=" << s4 << endl;
}
int main()
{
	test02();
	return 0;
}

在这里插入图片描述

3.string赋值操作

在这里插入图片描述
函数原型

-string& operator=(const char* s);      // char*类型字符串赋值给当前的字符串
-string& operator=(const string &s)   //把字符串s赋给当前的字符串
-string& operator=(char c) ;                //字符赋值给当前的字符串
-string& assign(const char *s) ;		   //把字符串s赋给当前的字符串
-string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
-string& assign(const string &s) ;       //把字符串s赋给当前字符串
-string& assign(int n,char c) ;            //用n个字符c赋给当前字符串

程序

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

//string的赋值操作

/*
-string& operator=(const char* s);      // char*类型字符串赋值给当前的字符串
-string& operator=(const string &s)     //把字符串s赋给当前的字符串
-string& operator=(char c) ;            //字符赋值给当前的字符串
-string& assign(const char *s) ;		//把字符串s赋给当前的字符串
-string& assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串
-string& assign(const string &s) ;      //把字符串s赋给当前字符串
-string& assign(int n,char c) ;         //用n个字符c赋给当前字符串
*/
void test02()
{
	string str1;
	str1 = "hello world";
	cout << "str1=" << str1 << endl;

	string str2;
	str2 = str1;
	cout << "str2=" << str2 << endl;

	string str3;
	str3 = 'a';
	cout << "str3=" << str3 << endl;

	string str4;
	str4.assign("hello C++");
	cout << "str4=" << str4 << endl;

	string str5;
	str5.assign("hello C++",5); //把字符串s的前n个字符赋给当前的字符串
	cout << "str5=" << str5 << endl;

	string str6;
	str6.assign(str5); //把字符串s的前n个字符赋给当前的字符串
	cout << "str6=" << str6 << endl;

	string str7;
	str7.assign(10,'w');
	cout << "str7=" << str7 << endl;
}
int main()
{
	test02();
	return 0;
}

在这里插入图片描述

4.string的拼接操作

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

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

//string的赋值操作

/*
-string& operator+=(const char* str) ;//重载+=操作符
-string& operator+=(const char c);//重载+=操作符
-string& operator+=(const string& str);//重载+=操作符
-string& append (const char *s);//把字符串s连接到当前字符串结尾
-string& append(const char *s, int n) ;//把字符串s的前n个字符连接到当前字符串结尾
-string& append(const string &s);//同operator+=(const string& str)
-string& append(const string &s,int pos,int n);//字符串s中从pos开始的n个字符连接到字符串结尾
*/
void test02()
{
	string str1="我";
	str1 += "爱玩游戏";
	cout << "str1=" << str1 << endl;

	str1 += ":";
	cout << "str1=" << str1 << endl;

	string str2="LOL";
	str1 += str2;
	cout << "str1=" << str1 << endl;

	str1.append(" and DNF");
	cout << "str1=" << str1 << endl;

	string str3 = "I ";
	str3.append("love you !",5);
	cout << "str3=" << str3 << endl;

	str3.append("you !");
	cout << "str3=" << str3 << endl;

	string str4 = "我 ";
	str4.append(str3,2,11);//下标从0开始
	cout << "str4=" << str4 << endl;
}
int main()
{
	test02();
	return 0;
}

在这里插入图片描述

5.string查找和替换

功能描述:
·查找:查找指定字符串是否存在
·替换:在指定的位置替换字符串

函数原型

int find(const string& str, int pos = ) const;//查找str第一次出现位置,从pos开始查找

int find( const char* s , int pos = 0) const;//查找s第一次出现位置,从pos开始查找

int find(const char* s , int pos, int n) const;//从pos位置查找s的前n个字符第一次位置

int find(const char c, int pos = e) const;//查找字符c第一次出现位置

int rfind(const string& str, int pos = npos ) const;//查找str最后一次位置,从pos开始查找

int rfind(const char* s , int pos - npos ) const;//查找s最后一次出现位置,从pos开始查找

int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后一次位置

int rfind(const char c, int pos = e) const;//查找字符c最后一次出现位置

string& replace(int pos, int n, const string& str);//替换从pos开始n个字符为字符串str

string& replace(int pos, int n,const char* s ) ;//替换从pos开始的n个字符为字符串s

1.查找

//rfind和find 区别
//find从左往右找;
//rfind从右往左找; 但是他们的pos还是按照从左往右的顺序的序号,下标从0开始

//1.查找
void test01()
{
	string str1 = "abcdef";

	//find
	int pos = str1.find("de");
	if (pos == -1)
		cout << "未找到" << endl;
	else
		cout << "pos=" << pos << endl;

	//rfind
	//rfind和find 区别
	//find从左往右找;
	//rfind从右往左找; 但是他们的pos还是按照从左往右的顺序的序号,下标从0开始
	int rpos = str1.rfind("de");
	if (rpos == -1)
		cout << "未找到" << endl;
	else
		cout << "rpos=" << rpos << endl;
}

在这里插入图片描述
注意:
虽然rfind从右往左找; 但是他们的pos还是按照从左往右的顺序的序号,下标从0开始

往我们把改成 string str1 = “abcdefde”;
find(de),从左往右第一个d下标为3;
rfind(de),从右往左第一个d下标为6;(下标顺序还是从左往右的)
在这里插入图片描述
//替换

//替换
void test02()
{
	string str1 = "abcdef";
	string str2 = "123456";

	//从1号位置起,3个字符“bcd”替换为字符串str2的"123456"
	str1.replace(1,3,str2);
	cout << "str1=" << str1 << endl;
}

在这里插入图片描述

在这里插入图片描述

完整程序

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

//字符串的查找和替换

//1.查找
void test01()
{
	string str1 = "abcdefde";

	//find
	int pos = str1.find("de");
	if (pos == -1)
		cout << "未找到" << endl;
	else
		cout << "pos=" << pos << endl;

	//rfind
	//rfind和find 区别
	//find从左往右找;
	//rfind从右往左找; 但是他们的pos还是按照从左往右的顺序的序号,下标从0开始
	int rpos = str1.rfind("de");
	if (rpos == -1)
		cout << "未找到" << endl;
	else
		cout << "rpos=" << rpos << endl;
}
//替换
void test02()
{
	string str1 = "abcdef";
	string str2 = "123456";

	//从1号位置起,3个字符“bcd”替换为字符串str2的"123456"
	str1.replace(1,3,str2);
	cout << "str1=" << str1 << endl;
}
int main()
{
	test01();
	test02();
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【P186 20】C++ 容器快速入门 (vector、deque、list、map、set...)(超详细) 的相关文章

随机推荐

  • 重学Java(四):操作符

    之前我写了一篇 重学Java 四 对象 引用 堆 栈 堆栈 本以为凭借自己8年的Java编程经验足够把这些 吃人 的Java名词解释清楚了 但有网友不以为然 在文章底部评论说 老哥 你真的有8年java开发经验么 告诉我 为什么要用三个句号
  • SylixOS系统简介

    SylixOS是一款嵌入式硬实时操作系统 同其类似的操作系统 全球比较知名的还有VxWorks 主要应用于航空航天 军事与工业自动化领域 RTEMS 起源于美国国防部导弹与火箭控制实时系统 ThreadX 主要应用于航空航天与数码通讯 等
  • 正确理解MySQL的MVCC及实现原理

    MVCC多版本并发控制 目录 MVCC多版本并发控制 前提概要 什么是MVCC 什么是当前读和快照读 当前读 快照读和MVCC的关系 MVCC的实现原理 隐式字段 undo日志 Read View 读视图 整体流程 MVCC相关问题 RR是
  • GlobalCorsConfig跨域文件

    package com config import org springframework context annotation Bean import org springframework context annotation Conf
  • Zabbix的基本使用

    文章目录 一 认识Zabbix 1 简介 2 功能 3 架构 4 数据流 二 项目 1 软件安装和环境部署 2 Zabbix工具的使用 1 创建被控主机 2 中文乱码修复 3 自动发现主机 4 自动注册主机 3 zabbix的API调用 4
  • Pandas中DataFrame的基本操作(增删)

    这是一篇最基础的Pandas用法总结 也方便自己日后进行复习与查询 这一次我们来总结一下Pandas中的一些增删改基本操作 df pd DataFrame F 90 88 85 M 75 97 74 F 82 73 91 M 93 99 9
  • Nginx的rewrite重写跳转和location匹配

    目录 常用的Nginx 正则表达式 location大致可以分为三类 location 常用的匹配规制 location优先级 location示例说明 实际网站使用中 至少有三个匹配规则定义 第一个必选规则 第二个必选规则是处理静态文件请
  • 设计模式-01-模糊理解

    一 概念 设计模式 别人都说它们就像是一个个的模型胚子 不管你们是多么的杂乱无章 只要经过它们的改造 表现出来的就都会是工工整整 标标准准的 而我觉得更确切的比喻应该是像一个制砖块儿的模具 虽然我们不知道为什么砖块儿 不仅要结实 也要外表光
  • python换零钱_Python3算法实例 1.2:动态规划 之 换零钱

    money jpg 问题 基础版 把100元兑换成1元 2元 5元 10元 20元 50元的零钱 共有多少种不同换法 动态规划思想解析 拆解子问题 下面以5元换成1 2 3元的零钱为例 T change target 表示用零钱序列chan
  • mybatisPlus之getById和selectById查询不出结果

    最终导致查询不出结果的原因可能有多种 我这里说出我遇到的一种原因 希望对你有帮助 我是因为在数据库添加了一个字段 没有及时地更新mapper xml中的resultMap导致的 大晚上的写代码 脑子不太好使 2 最近又遇到了一种情况 我数据
  • C 语言设置 Console 文字和背景的颜色的方法

    最近写的一个程序需要在 Console 窗口中输出大量的信息 大量的信息混在一起看着实在是费劲 因此就想到不同的信息用不同的颜色来输出 上网查了一番 win32 API 中有一个函数 SetConsoleTextAttribute 可以做这
  • 【目标检测】49、YOLOF

    文章目录 一 背景 二 方法 2 1 使用 SiSo 代替 MiMo 2 2 使用 Uniform matching 代替 Max IoU matching 2 3 YOLOF 的结构 三 效果 论文 You Only Look One l
  • linux常用命令-part2

    Ubuntu Fedora Debian CentOS中文怎么发音 有奔头 费德勒 迪扁 桑托斯 乌版图 菲朵拉 德槟 森头斯 使用find和wc命令统计代码行数 wc l find name js xargs 查看当前目录下文件的个数 l
  • 【用YOLOv3-tiny对TT100K进行训练】

    用YOLOv3 tiny对TT100K进行训练 数据集的处理 TT100K YOLO Label代码如何使用 修改数据集的配置文件 开始训练 训练意外中断怎么办 第一次跑代码 过程艰辛 值得记录 数据集的处理 YOLO对于数据集标签的格式有
  • oracle11g在没DNS情况下failover的配置方法

    1 Oracle 11g引入scan ip 可在没有DNS的情况下 客户端连接RAC配置failover时 很多情况还是使用oracle10g方式 即在客户端tnsname ora中配置failover 1 当客户端配置如下时 连接的实例关
  • 直线电机原理动画_直线振动筛工作原理结构图以及结构解析

    很多用户在使用直线振动筛的时都没有好好的研究过 该设备有哪些结构特点 从而造成了很多的使用上的问题 那么今天小编就为大家简单的介绍一下 如下所示 1 工作原理 直线振动筛为双电机驱动 利用电机里的偏心块的振动带动筛网和物料的振动 从而完成物
  • python summary结果提取_从Python中的OLS Summary获取DurbinWatson和JarqueBera统计信息

    OLS是一个运行值的汇总列 OLS的一部分是Durbin Watson和Jarque Bera JB 的统计数据 我想直接提取这些值 因为它们已经被计算出来了 而不是像我现在对durbinwatson那样运行这些步骤 在 下面是我的代码 i
  • 【力扣】455、分发饼干

    var findContentChildren function g s g 孩子的胃口 s 饼干尺寸 let arr g sort a b gt return a b let brr s sort a b gt return a b 初始
  • 【Flutter】十八、Flutter中常用的布局容器——列表布局ListView、ListTile

    一 ListView 1 1 创建ListView的多种方式 1 1 1 ListView 1 1 2 ListView builder 1 1 3 ListView separated 1 1 4 ListView custom 二 Li
  • 【P186 20】C++ 容器快速入门 (vector、deque、list、map、set...)(超详细)

    P186 20 C 容器快速入门 一 vector容器 1 vector存放内置数据类型 1 六种遍历方式 六种遍历方式 完整代码总览 部分遍历详解 2 初始化 区别 1 默认初始化 无参 没给定数组大小 2 带参数构造初始化 给定数组大小