算法学习第一弹——C++基础
早上好啊,大佬们。来看看咱们这回学点啥,在前不久刚出完C语言写的PTA中L1的题目,想必大家都不过瘾,感觉那些题都不过如此,所以,为了我们能更好的去处理更难的题目,小白兔决定奋发图强,开始学习C++算法。
前言:对于算法学习中,为了使算法更加容易成型,会很常用到STL库,这个也是C++中区别于C很大的一个板块,所以我们在正式开始学习算法之前先简单说一说C++的语法和STL库。
注:本篇所写代码提供:
链接:https://pan.quark.cn/s/d7565311ef3a
提取码:Zp6D
C++语言基础
如果把C语言比作是在做菜,那C++就是把几个预制菜加热放到一起。咱先不论菜的味道,单纯评价速度,想必C++会快很多。
对于两者之间的差别说大不大,说小也不小,最主要的就是两个的编程方式,一个是面向过程的编程,另一个是面向对象的编程方式。对于两者的区别,我们后面专门出一期来评一评,这一期我们就先爽一爽,只管这个代码怎么写就好,那些理论的东西之后再谈。
然后事先说一下,我们是相对于C语言进行说明,只说一些两者之间的差别。
头文件
首先,最早见到的不同就是头文件,在C++中提供了很多好用的头文件:
<iostream>
:提供输入输出流功能,如cin
、cout
、cerr
。<iomanip>
:提供输入输出流的格式化操作,如setw
、setprecision
。<sstream>
:提供字符串流功能,允许对字符串进行输入输出操作。<vector>
:提供动态数组容器。<list>
:提供双向链表容器。<deque>
:提供双端队列容器。<set>
:提供基于红黑树的有序集合。<map>
:提供基于红黑树的有序键值对集合。<unordered_set>
和<unordered_map>
:提供基于哈希表的无序集合。<queue>
:提供队列容器适配器。<stack>
:提供栈容器适配器。<bitset>
:提供固定大小的位集合。
相较于C的那些头文件,C++中的这些头文件所包含的内容会更加全面好用。然后,C++还有一个很好用的头文件,它包含了C++中常用的大部分头文件,被称为万能头文件:
<bits/stdc++.h>
数据类型
然后是数据类型,在C++中增加 Bool 类型,这个类型讲起来比较容易,咱们简单带过一下:
首先是Bool型所包含的值只有 True(真) 和 False(假) 两种:
咱简单类比一下,在C语言中,对于一个整型数据,当它为0时,它对应的就是False,然后除了0以外,它对应的值是True。
#include <iostream>int main() {bool isFinished = false;if (isFinished) {std::cout << "The process is finished." << std::endl;} else {std::cout << "The process is still running." << std::endl;}return 0;
}
ok,这个咱就说到这里。
输入输出
在C语言里,我们的输入输出比较常用的是 scanf() 和 printf(),然后在C++里,<iostream>头文件里提供了另一种输入输出的方式 cin 和 cout。
cin
和cout
能够检查类型不匹配,这有助于避免类型错误,而scanf
和printf
需要手动指定类型,更容易出错。cin
和cout
是 C++ 的流对象,它们支持面向对象的特性,如继承和多态,而scanf
和printf
是 C 风格的函数,不具备这些特性。- 使用
cin
和cout
时,如果发生输入输出错误,会抛出异常,这使得错误处理更加灵活和强大。而scanf
和printf
不支持异常处理。 cout
可以使用<<
操作符和std::setw
、std::setprecision
等操作来控制输出格式,这些操作比printf
的格式化字符串更加直观和灵活。
#include <bits/stdc++.h>int main()
{//输入int a;scanf("%d", &a);std::cin >> a;//输出printf("%d", a);std::cout << a;return 0;
}
很直观得就能看出两者的差别,cin和cout在书写的时候会方便很多。
然后,可以在开始加一句,然后在后面的输入输出std::。
using namespace std;
#include <bits/stdc++.h>
using namespace std;int main()
{//输入int a;scanf("%d", &a);cin >> a;//输出printf("%d", a);cout << a;return 0;
}
但是,对于有些时候它并没有那么好用,cin 和 cout 的运行并没有 scanf 和 printf 那么快,所以对于一些时间复杂度很高的题目,输入输出很多的题目,还是用 scanf() 和 printf() 会比较好一些。
或者可以添加一句这个:
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
使用了它之后有一些变化:
- 提高执行效率
- 解绑输入输出流
- 使用后不能使用scanf(),printf()等
- 而且不能使用endl,cout << endl --> cout << '\n'
对于这方面好像就这这些了,相信各位C语言大佬们很快就能记住这些了吧。
还有一个类型需要讲一下——string,这个也是一个很重要的一个类型。
string:
头文件:<string>
在C语言里面有一个字符数组,也就是 char*,它和string很像,可以说string >= char*,所以大家在用string类型的时候可以类比char*的使用方法来运用,下面我来补充一点string>的部分。
char*是一个指针
string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。
string的基本内容:
声明和初始化:
#include <bits/stdc++.h>
using namespace std;int main()
{string s1;//std::string s; 如果没有加 using namespace std;这一句的话,就需要这么写string s2 = "Bunny Girl"; // 直接声明和初始化一个空的字符串string s3 = s1; //Bunny Girlstring s4 = s1.substr(1, 6); //unny Greturn 0;
}
赋值:
直接赋值创建:
#include <bits/stdc++.h>
using namespace std;int main()
{string s = "Bunny Girl";return 0;
}
cin输入:
#include <bits/stdc++.h>
using namespace std;int main()
{string s;cin >> s; // 这种输入和scanf("%s")一样,不能有空格输入。cout << s << endl;return 0;
}
getline()输入:
#include <bits/stdc++.h>
using namespace std;int main()
{string s;getline(cin, s);cout << s;return 0;
}
下面就开始重头戏了,大家做好准备喔,都是重点,都要好好学
基本操作:
存取
char& operator[](int n); //通过[]方式取字符
char& at(int n); //通过at方法获取字符
#include <bits/stdc++.h>
using namespace std;int main()
{string s1 = "bunny girl";cout << s1[2] << " "; //获取第三个字符cout << s1.at(4) << "\n"; //获取第五个字符s1[2] = 'b';s1.at(4) = 't';cout << s1.at(2) << " " << s1[4] << "\n"; return 0;
}/*
n y
b t
*/
获取长度
使用size或者length方法。
需要注意的是它和 C语言中 strlen()函数 的差别,strlen在遇到 ' \0 ' 时会停止后面的长度获取,但是size和length方法可以获取字符串真实长度。
我们来看看怎么个事儿:
#include <bits/stdc++.h>
using namespace std;int main()
{string s = "I am Bunny Girl";int len1 = s.size(); //15int len2 = s.length(); //15cout << len1 << "\n" << len2 << "\n";s[11] = '\0';int len3 = s.size(); //15int len4 = s.length(); //15cout << len3 << "\n" << len4 << "\n";//可见对于size和length方法是不会判断 ' \0 '来停止长度获取。 return 0;
}
拼接
在C++中提供了一种直接使用 +号 来进行连接的方式。
或者,可以使用append方法来进行连接。
#include <bits/stdc++.h>
using namespace std;int main()
{
/*
字符串拼接
*/string s1 = "I am ";string s2 = "Bunny Girl";string s3 = s1 + s2;cout << s3 << "\n";string s4 = "I am ";s1.append("Bunny Girl");cout << s1 << "\n";return 0;
}//结果
//I am Bunny Girl
//I am Bunny Girl
查找
C++里的字符串字串查找使用的函数是 —— find()
语法格式:
str.find(str, pos)
参数:
str 表示要查找的字符串
pos 表示从s的pos位置开始查找
由它引申的函数还有
find_first_of (str), 第一次出现的位置;
find_last_of (str), 最后一次出现的位置;
rfind(str,pos): 从pos开始,倒序查找符合条件的字符串;
find()函数在字符串中查找子串返回子串的首地址。和C语言中strstr()函数很像,只是在字符串中如果没有该子串时,返回的值从NULL变成了string::npos。
#include <bits/stdc++.h>
using namespace std;int main()
{
/*
字符串查找
*/string str = "Hello World, Hello C++, Hello bunny girl";size_t pos = str.find("Hello"); // 查找子串"Hello",返回第一次出现的第一个字符的下标if (pos != string::npos) {cout << "Found substring at position: " << pos << endl;} else {cout << "Substring not found" << endl;}size_t pos_no = str.find("Bunny Girl"); //查找不存在的子串if (pos != string::npos) {cout << "Found substring at position: " << pos_no << endl;} else {cout << "Substring not found" << endl;}size_t pos_1 = str.find_first_of("Hello"); //查找第一次出现的位置if (pos != string::npos) {cout << "Found substring at position: " << pos_1 << endl;} else {cout << "Substring not found" << endl;}size_t pos_2 = str.find_last_of("Hello"); //查找最后一次出现的子串的最后一位的位置if (pos != string::npos) {cout << "Found substring at position: " << pos_2 << endl;} else {cout << "Substring not found" << endl;}size_t pos_3 = str.rfind("Hello"); //从后往前查找if (pos != string::npos) {cout << "Found substring at position: " << pos_3 << endl;} else {cout << "Substring not found" << endl;}return 0;
}/*
结果
Found substring at position: 0
Found substring at position: 18446744073709551615
Found substring at position: 0
Found substring at position: 39
Found substring at position: 24
*/
替换
C++中,string::replace 有四种重载形式:
第一种:
string& replace (size_t pos, size_t len, const string& str);
从pos位置开始,长度为len的子串 替换为新的str字符串。
第二种:
string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
新增了subpos和sublen两个参数,分别表示新字符串str的子串的起始位置和长度。
第三种:
template <class InputIterator>string& replace (iterator i1, iterator i2, InputIterator first, InputIterator last);
使用迭代器来表示需要被替换的子串的范围(i1到i2),以及新的字符串的范围(first到last)。
第四种:
string& replace (size_t pos, size_t len, const char* s);
可以接受一个C风格的字符串(也就是字符数组)作为新的字符串。
下面我演示一下这些用法:
#include <bits/stdc++.h>
using namespace std;int main()
{
/*
字符串替换
*/string str1 = "I am @ a@ bunny girl";str1.replace(0, 4,"rabit is"); //从第一个a位置开始的两个字符替换成#cout<<str1<<endl;string str2 = "I am @ a@ bunny girl";string str_temp = "rabit is";str2.replace(str2.begin(), str2.begin()+4, str_temp); //从第一个a位置开始的两个字符替换成#cout<<str2<<endl;string str3 = "I am @ a@ bunny girl";string str_temp1 = "rabit is";str3.replace(str3.begin(), str3.begin()+4, str_temp1.begin(), str_temp1.end()); //从第一个a位置开始的两个字符替换成#cout<<str3<<endl;return 0;
}/*
结果
rabit is @ a@ bunny girl
rabit is @ a@ bunny girl
rabit is @ a@ bunny girl
*/
获取子串
语法格式:
str.substr(size_type _Off = 0,size_type _Count = npos)返回值: string,包含s中从pos开始的len个字符的拷贝(pos的默认值是0,len的默认值是s.size() - pos,即不加参数会默认拷贝整个s)
异常 :若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾
#include <bits/stdc++.h>
using namespace std;int main()
{string s1 = "bunny girl";string s2 = "white rabit";string s01 = s1.substr(0, 5);string s02 = s2.substr(6, 10);cout << s01 << "\n" << s02 << "\n";return 0;
}/*
bunny
rabit
*/
比较
我们也拿C语言进行类比,C语言里有一个函数是strcmp()函数,在C++里面是compare()函数。
compare()函数的语法格式:
int compare(const string &s)const; //与字符串s比较 int compare(const char *s)const; //与字符串s比较
比较结果,和strcmp()是一样的:
s1 == s2 --> 0
s1 > s2 --> 1
s1 < s2 --> 2
#include <bits/stdc++.h>
using namespace std;int main()
{string s1 = "bunny girl";string s2 = "bunny girl";string s3 = "abcdef";string s4 = "zxyw";if (s1.compare(s2) == 0){cout << "s1 == s2" << "\n";}if (s1.compare(s3) > 0){cout << "s1 > s3" << "\n";}if (s1.compare(s4) < 0){cout << "s1 < s4" << "\n";}return 0;
}/*
s1 == s2
s1 > s3
s1 < s4
*/
插入
string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c); //在指定位置插入n个字符c
#include <bits/stdc++.h>
using namespace std;int main()
{string s1 = "bunny girl";string s2 = "12345";s1.insert(2, s2);cout << s1;return 0;
}/*
bu12345nny girl
*/
删除
string& erase(int pos,int n=npos);//删除从Pos开始的n个字符
#include <bits/stdc++.h>
using namespace std;int main()
{string s1 = "bunny dsa girl";s1.erase(6, 4);cout << s1;return 0;
}/*
bunny girl
*/
总结
OK,那么这一期的内容就这么多,看完这些之后不要忘记刷题哦,只有在实战里面才能熟练基础。
下一期,我们开始讲STL库,小白兔会挑一些好用的容器来介绍一下,等过完这些内容就正式开始算法的学习咯,好好享受现在的美好时光吧。
小白兔把这一期里写的代码放到网盘里了,大家可以留作复习,常看常新喔。
那么Bye Bye咯,咱们下期见。
相关文章:

算法学习第一弹——C++基础
早上好啊,大佬们。来看看咱们这回学点啥,在前不久刚出完C语言写的PTA中L1的题目,想必大家都不过瘾,感觉那些题都不过如此,所以,为了我们能更好的去处理更难的题目,小白兔决定奋发图强࿰…...

javaWeb小白项目--学生宿舍管理系统
目录 一、检查并关闭占用端口的进程 二、修改 Tomcat 的端口配置 三、重新启动 Tomcat 一、javaw.exe的作用 二、结束javaw.exe任务的影响 三、如何判断是否可以结束 结尾: 这个错误提示表明在本地启动 Tomcat v9.0 服务器时遇到了问题,原因是所需…...

如何优化Elasticsearch的查询性能?
优化Elasticsearch查询性能可以从以下几个方面进行: 合理设计索引和分片: 确保设置合理的分片和副本数,考虑数据量、节点数和集群大小。根据数据量和节点数量调整分片数量,避免使用过多分片,因为每个分片都需要额外的…...
蓝桥杯每日真题 - 第12天
题目:(数三角) 题目描述(14届 C&C B组E题) 解题思路: 给定 n 个点的坐标,计算其中可以组成 等腰三角形 的三点组合数量。 核心条件:等腰三角形的定义是三角形的三条边中至少有…...
从H264视频中获取宽、高、帧率、比特率等属性信息
背景 最近整理视频编解码的代码,早前在jetson上封装了jetson multimedia作为视频编解码的类,供其他同事和其他组使用,但该解码接口有一个问题,无法首先获取视频宽高信息,更无法直接获取视频的帧率、比特率等信息。 解…...

Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件
前一篇文章中讲述了如何使用cyberchef提取HTTP/TLS数据包中的文件,详见《Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件》,链接这里,本文讲述下如何使用cyberchef提取FTP/TCP数据包中的文件。 FTP 是最为常见的文件传输协议,和HTTP协议不同的是FTP协议传输…...

Nginx中使用keepalive实现保持上游长连接实现提高吞吐量示例与测试
场景 HTTP1 .1之后协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应, 减少了建立和关闭连接的消耗和延迟。 如果我们使用了nginx去作为反向代理或者负载均衡,从客户端过来的长连接请求就会被…...

深度学习-卷积神经网络CNN
案例-图像分类 网络结构: 卷积BN激活池化 数据集介绍 CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像,图像大小32323。下图列举了10个类,每一类随机展示了10张图片: 特征图计算 在卷积层和池化层结束后, 将特征…...
241114.学习日志——[CSDIY] [Cpp]零基础速成 [03]
CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!࿰…...

大模型研究报告 | 2024年中国金融大模型产业发展洞察报告|附34页PDF文件下载
随着生成算法、预训练模型、多模态数据分析等AI技术的聚集融合,AIGC技术的实践效用迎来了行业级大爆发。通用大模型技术的成熟推动了新一轮行业生产力变革,在投入提升与政策扶植的双重作用下,以大模型技术为底座、结合专业化金融能力的金融大…...

数据库SQL——什么是实体-联系模型(E-R模型)?
目录 什么是实体-联系模型? 1.实体集 2.联系集 3.映射基数 一对一(1:1) 一对多(1:n) 多对一(n:1) 多对多(m:n) 全部参与: 4.主码 弱实体集…...
在 MySQL 8.0 中,SSL 解密失败,在使用 SSL 加密连接时出现了问题
在 MySQL 8.0 中,SSL 解密失败通常指的是在使用 SSL 加密连接时出现了问题,导致无法建立加密通信。这个问题可能由多种原因引起,下面是一些常见的原因和排查方法: 1. 证书配置问题 确保您在 MySQL 配置中使用了正确的 SSL 证书和…...
React Native 全栈开发实战班 - 第四部分:用户界面进阶之动画效果实现
在移动应用中,动画效果 是提升用户体验的重要手段。合理的动画设计可以增强应用的交互性、流畅性和视觉吸引力。React Native 提供了多种实现动画的方式,包括内置的 Animated API、LayoutAnimation 以及第三方库(如 react-native-reanimated&…...
【CICD】GitLab Runner 和执行器(Executor
GitLab Runner 和执行器(Executor)是 GitLab CI/CD 管道中的两个重要组成部分。理解它们之间的关系有助于更好地配置和使用 CI/CD 流水线。runer是gitlab的ci-agent对接gitlab,而执行器是接受runer下发的ci的任务来干活的。也就是说gitrunner…...

实用教程:如何无损修改MP4视频时长
如何在UltraEdit中搜索MP4文件中的“mvhd”关键字 引言 在视频编辑和分析领域,有时我们需要深入到视频文件的底层结构中去。UltraEdit(UE)和UEStudio作为强大的文本编辑器,允许我们以十六进制模式打开和搜索MP4文件。本文将指导…...
mysqldump命令搭配source命令完成数据库迁移备份
mysqldump 命令使用 需保证mysqld在运行中, 这个命令的目的是将数据库导出到文件中,例如 mysqldump -uusername -ppassword database > db.sql 注意该命令不是在MySQL客户端(即MySQL命令行)执行的,而是在系统命…...

生信:TCGA学习(R、RStudio安装与下载、常用语法与常用快捷键)
前置环境 macOS系统,已安装homebrew且会相关命令。 近期在整理草稿区,所以放出该贴。 R语言、RStudio、R包安装 R语言安装 brew install rRStudio安装 官网地址:https://posit.co/download/rstudio-desktop/ R包下载 注意R语言环境自带…...

十三、注解配置SpringMVC
文章目录 1. 创建初始化类,代替web.xml2. 创建SpringConfig配置类,代替spring的配置文件3. 创建WebConfig配置类,代替SpringMVC的配置文件4. 测试功能 1. 创建初始化类,代替web.xml 2. 创建SpringConfig配置类,代替spr…...
为什么海外服务器IP会被封
海外服务器因为免备案而备受用户欢迎,近年来租用海外服务器的用户也越来越多,自然也可能会出现一些问题。 如果服务器IP被封,在该服务器下的所有业务都无法访问,对自己和对用户来说都会有较大的影响。因此,我们应做好相…...
图像处理技术椒盐噪声
椒盐噪声,也称为脉冲噪声,是图像中经常见到的一种噪声。它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。这些白点和黑点会在图像中随机分布,导致图像中…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...