C++学习笔记(七)

一、string字符串容器

#include <iostream>using namespace std;int main()
{string name;name = "hello";string str(10,'w');cout << str << endl;name = "hello world";string sub1(name,0,5);cout << sub1 << endl;4string sub2("www.hqyj.com");cout << sub2 << endl;string sub3(sub2.begin() + 4,sub2.begin() + 8);cout << sub3 << endl;//string* str3 = new string();string str3 = "hello world";//string容器对象中使用迭代器遍历有效元素的方式:
-----------------------------------------------------------------------------------------------//逆序for(string::reverse_iterator it = str3.rbegin(); it != str3.rend(); ++it){cout << *it << " ";}cout << endl;
---------------------------------------------------------------------------------------//正序
---------------------------------------------------------------------------------------//    for(string::iterator it = str1.begin();it != str1.end();++it)//    {//        cout << *it <<" ";//    }//    cout << endl;------------------------------------------------------------------//枚举for循环遍历:必须有迭代器的支持:for(char s : str3){cout << s << " ";}cout << endl;//获取string对象的有效字符的个数:cout << str3.size() << endl;cout << str3.max_size() << endl;string str5;for(int i = 0; i < 20; i++){cout << "str5的有效的字符个数:" << str5.size() << "str5的有效的空间大小" << str5.capacity() << endl;//string的栈上容器对象默认起始空间为15bytes,之后按按照2倍扩容的方式进行扩容。str5.push_back('a');}//后符字符串到结尾,改变原字符串对象:string str6  = "hello";cout << str6.append("world") << endl;cout << str6.replace(0,5,"Big") << endl;string str7 = "1314";cout << stoi(str7) + 100 << endl;return 0;
}

二、vector容器

ector容器:(单向开口的连续内存空间)
--------------------vector与array无乎是一样的,连续的存储结构,两者的唯一的区别在于在空间上的灵活,数组需要提前指定长度,不量确定了就不能发生改变了,比较死板,不够灵活。
----------------------------------------vector容器是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新的元素。vector中的默认的空间配置策略是2倍进行扩容的。
---------------------------------------------------------------
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;for(int i = 0; i < 20; i++){cout << "vector中的有效元素个数:" << v.size() << " ,vector的有效空间大小" << v.capacity() << endl;v.push_back(rand() % 100 + 1);}//遍历vector中的元素:for(vector<int>::iterator it = v.begin(); it != v.end(); ++it){cout << *it << " ";}cout << endl;//有迭代器支持的枚举for循环:for(int k : v){cout << k << " ";}cout << endl;//原始的C的方式:for(int i = 0; i < v.size();i++){cout << v[i] <<  " ";}cout << endl;return 0;
}迭代器非法化(迭代器失效问题)
--------------------------------------------通过迭代器解引用之后找到的值并非原来的值,因为插入或擦除之后该地址上的元素发生了移动,通过迭代器解引用后是不能得到与之前的值相同的内容。---------------------------------解决方法:
-------------
使用insert或erase时,使用返回值更新一下迭代器-------------------------------------------
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;for (int i = 0; i < 20; i++){cout << "vector中的有效元素个数:" << v.size() << " ,vector的有效空间大小" << v.capacity() << endl;v.push_back(rand() % 100 + 1);}//遍历vector中的元素:for (vector<int>::iterator it = v.begin(); it != v.end(); ++it){cout << *it << " ";}cout << endl;//有迭代器支持的枚举for循环:for (int k : v){cout << k << " ";}cout << endl;//原始的C的方式:for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;//需求:在20随机数中偶数前插入一个88的值:for (auto it = v.begin(); it != v.end(); ++it){if (*it % 2 == 0){//请务必:使用返回值更新一下迭代器:it = v.insert(it, 88);it++;}}for (int k : v){cout << k << " ";}cout << endl;cout << "---------------------------------------" << endl;//需求:把所有的偶数删除:for (auto it = v.begin(); it != v.end();){if (*it % 2 == 0){//请务必:使用返回值更新一下迭代器:it = v.erase(it);}else {it++;}}for (int k : v){cout << k << " ";}return 0;
}

三、deque容器

deque:双向开口的连续线性空间-----------------------------------------头尾两端分别做元素的插入和删除

四、容器适配器

容器适配器是没有迭代器,是不能使用泛型算法的
------------------------------------------------------------栈:
-------------------------------------------
#include <iostream>
#include <deque>using namespace std;template <class T, class Container = deque<T>>class Stack
{
private:Container _container;public:void push(const T& val){this->_container.push_front(val);}void pop(){this->_container.pop_front();}T& top(){return this->_container.front();}bool empty(){return this->_container.empty();}
};int main()
{Stack<int> s;s.push(1);s.push(2);s.push(3);while (!s.empty()) {cout << s.top() << endl;s.pop();}return 0;
}---------------------------------------------------优先级队列:
--------------------#include <iostream>
#include <vector>
#include <algorithm>using namespace std;template <class T,class Container = vector<T>, class Compair = std::less<T>>
class Priority_queue
{
private:Container _container;Compair _compair;public:void push(const T& val){this->_container.push_back(val);sort(this->_container.begin(),this->_container.end(),this->_compair);}void pop(){this->_container.pop_back();}T& top(){return this->_container.back();}bool empty(){return this->_container.empty();}
};
int main()
{Priority_queue<int> pq;for(int i = 0; i < 20; i++){pq.push(rand() % 100 + 1);}while (!pq.empty()) {cout << pq.top() << " ";pq.pop();}return 0;
}优先级队列标准库中使用的堆排序:
----------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T,class Container = vector<T>, class Compair = std::less<T>>
class Priority_queue
{
private:Container _container;Compair _compair;
public:Priority_queue(){make_heap(this->_container.begin(),this->_container.end(),this->_compair);}void push(const T& val){this->_container.push_back(val);push_heap(this->_container.begin(),this->_container.end(),this->_compair);}void pop(){pop_heap(this->_container.begin(),this->_container.end(),this->_compair);this->_container.pop_back();}T& top(){return this->_container.front();}bool empty(){return this->_container.empty();}
};
int main()
{Priority_queue<int> pq;for(int i = 0; i < 20; i++){pq.push(rand() % 100 + 1);}while (!pq.empty()) {cout << pq.top() << " ";pq.pop();}return 0;
}

五、list容器

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表链接次序实现的
------------------------------------------------------------------------------------------------------------------------
List容器:
------------------
双向循环链表
-------------------------------------------
在list中插入或删除元素时,不会引用非它元素的迭代器的失效。在listAPI有专门的排序算法。
--------------------------------------------------------------------
list相关API接口:
------------------------
#include <iostream>
#include <list>using namespace std;int main()
{list<int> ll;for(int i = 0; i < 20; i++){ll.push_front(rand() % 100 + 1);}ll.sort([](int val1, int val2){return val1 > val2;});for(int k : ll){cout << k << " ";}cout << endl;return 0;
}-------------------------------------------

六、set容器

-------------------------------------
非线性容器之set/multiset容器(俗称有序容器)树结构,平衡二叉树
-------------------------set容器的数据结构:
---------------------------------
Set特性是:所有元素都会根据元素的键值自动被排序。(set 与 map都会按照键值来自动排序,只不过set的键与值是一体的相同的)Set的元素不像map那样,可以同时拥有实值与键值,set的元素即是键值又是实值。(你也可以理解为只有一个值,键与值相同)Set不允许两个元素有相同的键值。(即然是自动排序,set与map是不允许有相同的键的存在。这一点与map是共同的。),而multiset是可以存相同键值的元素。(这是set与multiset的唯一区别。)。所以set容器的迭代器是一个常双向迭代器,只支持什么:++--==!=的操作。--------------------------------------------------------------
我们可以通过set的迭代器改变set元素的值吗?
-----------------------------------------------------------不行,因为set元素值就是其键值,关系到set元素排序规则,如果任意改变set元素值,会严重破坏set组织结构。换句话说,set的迭代器是一个只读迭代器。set容器拥有与list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有迭代器,在操作完成之后依multiset的底层实现是红黑树,红黑树是平衡二叉树的一种。
-----------------------------------------------------------------------set相关API的介绍及相关策略
-------------------------------------#include <iostream>
#include <set>
using namespace std;
class Stu
{
private:string name;int id;
public:Stu(string name, int id){this->name = name;this->id = id;}void showInfo(){cout << "学号:" << this->id << " ,姓名:" << this->name << endl;}//如果要把一个自定义对象插入到set集合中,那么请重载<运算符,并以const修饰。bool operator<(const Stu& other)const{return this->id < other.id;}
};int main()
{//set集合最大的用法:就是去重操作及自动排序。set<int> s;std::pair<set<int>::iterator,bool> p;for(int i = 0; i < 20; i++){p = s.insert(rand() % 100 + 1);if(!p.second){cout << *p.first << "没有插入成功" << endl;}}for(int k : s){cout << k << " ";}cout << endl;cout << "---------------------------------------------" << endl;Stu stu1("zhangsan",1003);Stu stu2("lisi",1001);Stu stu3("wangWu",1002);set<Stu> s1;s1.insert(stu1);s1.insert(stu2);s1.insert(stu3);for(Stu stu : s1){stu.showInfo();}return 0;
}
-----------------------------------------------------------
如果,使用自定义类型插入到这个set容器中,要么在自定义类型中定义<号运算符重载函数,要么自定义一个函数对象类型,并重写小括号运算符重载函数。
---------------------------------------

七、对组pair

对组的构造的方式:
------------------------------------------------------
#include <iostream>
#include <map>
using namespace std;int main()
{pair<int, string> p1 = {1001,"xialuo"};pair<int, string> p2(1002,"qiuya");pair<int, string> p3 = make_pair(1003,"yanhua");pair<int, string> p4 = map<int,string>::value_type(1004,"dongmei");//cout << p1.first << "," << p1.second;//把对组数据,插入到map集合中:map<int,string> m1;m1.insert(p4);m1.insert(p2);m1.insert(p3);m1.insert(p1);//map容器中的[]中括号运算符重载函数的副作用:m1[1005] = "dachun";m1[1006];m1[1005] = "zhangjian";m1.erase(1006);//遍历map:for(pair<int,string> p : m1){cout << p.first << " ," << p.second << endl;}//有边界检查:cout << m1.at(1001) << endl;//cout << m1.at(1008) << endl;//无边界检查:cout << m1[1001] << endl;//find查找:auto it = m1.find(1001);if(it != m1.end()){cout << "id:" << it->first << ",姓名:" << it->second << endl;}else {cout << "没有找到你所斯望的元素" << endl;}return 0;
}

八、Map容器

Map容器的特性是:所有元素都会根据元素的键的值自动排序。Map所有的元素都是统一的pair对组,同时拥有键值Key实值Value,pair的第一元素被视为键值,第二个元素被视为实值,map不允许两个元素有相同的键。--------------------------------------------------------
我们可以通过map迭代器改变map的键值吗?-------------------------------------------------------------答案是不行,因为map的键值关系到map的元素的排列布局,Map中的键是不可修改的,但是键对应的值是可以修改的。所以Map的迭代器是一个双向迭代器,只支持++ ===操作。Map是可以随时插入或删除键值对的。Map与multimap的唯一区别是multimap中的键是可以重复的。Map的底层实现机制是由二叉树中的红黑树进行实现的。------------------
总结:
------------------map容器的最小单位是pair对组,在这个容器中,我们可以通过pair对组的Key通过[ ]中括号运算符或find方法,找到与之对应的实值,所以Key与Value之间成映射关系。所以map容器也被称之映射表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/798147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第四百四十六回

文章目录 1. 概念介绍2. 使用方法3. 示例代码4. 经验与总结4.1 经验分享4.2 内容总结 我们在上一章回中介绍了"overlay_tooltip简介"相关的内容&#xff0c;本章回中将再谈flutter_launcher_icons包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…

python练习三

模式A num int(input("请输入模式A的层数&#xff1a;")) for i in range(1, num 1):# 画数字for j in range(1, i 1):print(str(j) "\t", end"")print() 模式B num int(input("请输入模式B的层数&#xff1a;")) for i in ran…

Pandas中的 .map 方法

1. Pandas中的 .map 方法 在Pandas中&#xff0c;.map 方法通常用于Series对象&#xff0c;它允许你根据一个字典或者函数对Series中的每个元素进行转换。 import pandas as pd # 创建一个简单的DataFrame df pd.DataFrame({ Name: [Alice, Bob, Charlie, Alice, Bob, C…

redis-Hash

一&#xff0c;应用场景 Redis hash 是一个string类型的field和value的映射表&#xff0c;hash特别适合用于存储对象。Set就是一种简化的Hash,只变动key,而value使用默认值填充。 可以将一个Hash表作为一个对象进行存储&#xff0c;表中存放对象的信息。 二&#xff0c;命令 H…

Ubuntu18.04安装Node.js教程

在Ubuntu 18.04上安装Node并部署环境变量的过程可以分为以下几个步骤&#xff1a; 安装Node.js 您可以选择从Ubuntu的软件源直接安装Node.js&#xff0c;或者使用NodeSource提供的仓库安装特定版本的Node.js。 从Ubuntu软件源安装 运行以下命令来更新软件包列表并安装Node.js&…

【stm32】SPI通信简介

SPI通信 SPI简介部分 所有SPI设备的SCK、MOSI、MISO分别连在一起 从主机引出多根SS选择线&#xff0c;分别接到每个从机的SS输入端&#xff0c;主机的SS线都是输出&#xff0c;从机的SS线都是输入&#xff0c;SS线 是低电平有效&#xff0c;同一时间主机只能选择一个从机 只能…

LeetCode 1780. 判断一个数字是否可以表示成三的幂的和

解题思路 该题目可以等价于求三进制的数&#xff0c;把>1的数 return false,剩下的 return true. 相关代码 class Solution {public boolean checkPowersOfThree(int n) {//该题目可以等价成不断地除以3&#xff0c;当余数>1时&#xff0c;则为falsewhile(n>3){ …

cmake学习笔记1

基础概念 CMake是什么&#xff1f; CMake是一个元构建系统(meta build-system),用于生产其他构建系统文件&#xff08;如Makefile或Ninja&#xff09;。 基础操作方式 CMake使用一个CMakeLists.txt文件描述配置&#xff0c;然后使用cmake驱动这个文件生成对应构建系统文件。…

websokcet服务端实现

一/websokcet服务端实现 步骤一&#xff1a; springboot底层帮我们自动配置了websokcet&#xff0c;引入maven依赖 1 2 3 4 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</arti…

AI图片智能选区抠像解决方案

高质量的图片处理往往依赖于繁琐的手动操作&#xff0c;耗费大量时间与精力。美摄科技推出了一款革命性的AI图片智能选区抠像解决方案&#xff0c;旨在帮助企业轻松实现图片的高效处理&#xff0c;提升内容创作效率与质量。 美摄科技的AI图片智能选区抠像解决方案&#xff0c;…

AFCI 应用笔记二之数据采集

1. 简介 基于监督学习的神经网络算法需要大量数据作为输入&#xff0c;模型完全由数据驱动&#xff0c;其数据质量是算法有效的必要条件&#xff0c;所以如何高效的采集到数据&#xff0c;以及正确的标注或分析是极其重要的&#xff0c;如果第一步有问题&#xff0c;后续的所有…

C++搭建深度学习的推理框架

我们的目的是:借助C++搭建一个类似于pytorch,tensorflow的深度学习框架,对标pytorch,tensorflow实现对应的功能。由于本人能力有限,下面本人将借助C++搭建一个简单的全连接神经网络,并且尝试解释里面的算子定义和计算图构建。 算子定义 回顾pytorch里面搭建的全连接神经网…

ESP32S3网络编程学习笔记(1)—— Wi-Fi扫描实验

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动/单片机/RTOS的实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff…

基于DPDK的VPP 插件demo代码

VPP的插件编写&#xff0c; 首先要把VPP 工程下载下来&#xff0c; 编译通过。 然后按照example程序的套中来编写插件。 还有一个前提&#xff0c; 就是测试机上已经具备了DPDK 已经可用版本。 1. 下载VPP。 可以从github上下载VPP的指定版本的zip包&#xff0c; 也可以用…

2024年租用阿里云服务器多少钱一年?连夜整理分享

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

__ne__()函数详解

在Python中&#xff0c;ne 是一个特殊方法&#xff0c;用于定义不等于&#xff08;!&#xff09;操作符的行为。当你使用 ! 操作符来比较两个类的实例时&#xff0c;Python会自动调用这个方法。如果这个方法没有在你的类中定义&#xff0c;那么 ! 操作符会使用 eq 方法的结果来…

【C++】C++ primer plus 第十二章--类和动态内存分配

动态内存和类 关于静态数据成员 类之作声明&#xff0c;不分配内存&#xff0c;因此静态成员变量在类中不能进行初始化&#xff0c;需要在类外进行。特殊情况&#xff1a; 存在可以在类中声明静态成员并初始化的情况&#xff0c;成员类型为const整型或者const枚举类型。 特殊…

软考高级架构师:嵌入式系统的内核架构

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

2024/4/1—力扣—二叉树的最近公共祖先

代码实现&#xff1a; 思路&#xff1a; 递归判断左子树和右子树&#xff0c;查找p或者q是否在当前节点的子树上 1&#xff0c;在同一子树上&#xff0c;同一左子树&#xff0c;返回第一个找到的相同值&#xff0c;同一右子树上&#xff0c;返回第一个找到的相同值 2&#xff0…

Oracle23免费版简易安装攻略

installation-guide 1 安装 root用户下 wget https://yum.oracle.com/repo/OracleLinux/OL8/developer/x86_64/getPackage/oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm wget https://download.oracle.com/otn-pub/otn_software/db-free/oracle-database-free-23c-1…