算法学习第一弹——C++基础

news2024/11/23 20:17:02

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

前言:对于算法学习中,为了使算法更加容易成型,会很常用到STL库,这个也是C++中区别于C很大的一个板块,所以我们在正式开始学习算法之前先简单说一说C++的语法和STL库。

注:本篇所写代码提供:

链接:https://pan.quark.cn/s/d7565311ef3a
提取码:Zp6D

 C++语言基础

如果把C语言比作是在做菜,那C++就是把几个预制菜加热放到一起。咱先不论菜的味道,单纯评价速度,想必C++会快很多。

对于两者之间的差别说大不大,说小也不小,最主要的就是两个的编程方式,一个是面向过程的编程,另一个是面向对象的编程方式。对于两者的区别,我们后面专门出一期来评一评,这一期我们就先爽一爽,只管这个代码怎么写就好,那些理论的东西之后再谈。

然后事先说一下,我们是相对于C语言进行说明,只说一些两者之间的差别。

头文件

首先,最早见到的不同就是头文件,在C++中提供了很多好用的头文件:

  • <iostream>:提供输入输出流功能,如cincoutcerr
  • <iomanip>:提供输入输出流的格式化操作,如setwsetprecision
  • <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。

  1. cin 和 cout 能够检查类型不匹配,这有助于避免类型错误,而 scanf 和 printf 需要手动指定类型,更容易出错。
  2. cin 和 cout 是 C++ 的流对象,它们支持面向对象的特性,如继承和多态,而 scanf 和 printf 是 C 风格的函数,不具备这些特性。
  3. 使用 cin 和 cout 时,如果发生输入输出错误,会抛出异常,这使得错误处理更加灵活和强大。而 scanf 和 printf 不支持异常处理。
  4. cout 可以使用 << 操作符和 std::setwstd::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);

使用了它之后有一些变化:

  1. 提高执行效率
  2. 解绑输入输出流
  3. 使用后不能使用scanf(),printf()等
  4. 而且不能使用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 Girl

    string s4 = s1.substr(1, 6); //unny G

    return 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(); //15
    int len2 = s.length(); //15
    cout << len1 << "\n" << len2 << "\n";

    s[11] = '\0';
    int len3 = s.size(); //15
    int len4 = s.length(); //15
    cout << 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咯,咱们下期见。

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

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

相关文章

vue2 -- el-form组件动态增减表单项及表单项验证

需求 在数据录入场景(如订单信息录入)中,可根据实际情况(如商品种类增加)动态添加表单项(如商品相关信息)。包含必填项验证和数据格式验证(如邮箱、电话格式),防止错误数据提交。 效果 代码一 <template><div>

【GPTs】Get Simpsonized:一键变身趣味辛普森角色

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;GPTs指令&#x1f4af;前言&#x1f4af;Get Simpsonized主要功能适用场景优点缺点使用方式 &#x1f4af;小结 &#x1f4af;GPTs指令 中文翻译&#xff1a; 指令保护和安全规则&…

丹摩征文活动|CogVideoX-2b:从安装到上线,轻松搞定全过程!

CogVideoX-2b&#xff1a;从安装到上线&#xff0c;轻松搞定全过程&#xff01; CogVideoX简介 CogVideoX的推出标志着视频生成技术的一次重大突破。过去&#xff0c;如何在保持高效的同时提升视频质量一直是一个难题&#xff0c;但CogVideoX 通过其先进的3D变分自编码器&…

CocosCreator 构建透明背景应用(最新版!!!)

文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…

【H2O2|全栈】JS案例章节(三)——轮播图实现

目录 前言 开篇语 准备工作 需求 HTML和CSS 注意事项 原生JS实现 变量设置 方法设置 自动轮播与轮播销毁 翻页按钮 li点击切换指定图片 JQuery实现 变量设置 方法设置 自动轮播与轮播销毁 翻页按钮 li点击切换指定图片 结束语 前言 开篇语 本系列为短章节…

Vivado+Vscode联合打造verilog环境

一、Vivado下载安装 详细参考我另一篇文章&#xff1a; Vivado2022.2下载安装_fpga vivado下载-CSDN博客https://blog.csdn.net/weixin_61081689/article/details/143460790?spm1001.2014.3001.5501 二、Vscode下载安装 详细参考我另一篇文章&#xff1a; VscodeAnacond…

A20红色革命文物征集管理系统

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

【软考】系统架构设计师-计算机系统基础(1):计算机硬件

知识点汇总 1、指令集 精简指令集RISC&#xff1a;寄存器&#xff0c;硬布线&#xff0c;效率高&#xff1b;复杂指令集CISC&#xff1a;微程序控制技术&#xff0c;效率低&#xff1b; 2、奇偶校验码&#xff1a;码距是2&#xff08;出错位校验位&#xff09;&#xff0c;只…

掌握高级 SQL 技巧:提升数据查询和管理能力

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; SQL&#xff08;Structured Query Language&#xff09;是处理和管理关系型数据库的重要工具。随着数据量的增加和业务需求的复杂…

从无音响Windows 端到 有音响macOS 端实时音频传输播放

以下是从 Windows 端到 macOS 端传输音频的优化方案&#xff0c;基于上述链接中的思路进行调整&#xff1a; Windows 端操作 安装必要软件 安装 Python&#xff08;确保版本兼容且已正确配置环境变量&#xff09;。安装 PyAudio 库&#xff0c;可通过 pip install pyaudio 命令…

Python小试牛刀:第一次爬虫,获取国家编码名称

使用场景&#xff1a; 需要初始化国家&#xff08;地区表&#xff09;&#xff0c;字段有国家名称、国家编码等等。 解决方案&#xff1a; 使用requests发送请求&#xff0c;使用bs4解析得到的HTML&#xff0c;打开F12&#xff0c;查看元素&#xff0c;&#xff08;可以Ctrl…

“倒时差”用英语怎么说?生活英语口语学习柯桥外语培训

“倒时差”用英语怎么说&#xff1f; “倒时差”&#xff0c;这个让无数旅人闻之色变的词汇&#xff0c;在英语中对应的正是“Jet Lag”。"Jet" 指的是喷气式飞机&#xff0c;而 "lag" 指的是落后或延迟。这个短语形象地描述了当人们乘坐喷气式飞机快速穿…

图书推荐 | Python金融大数据分析快速入门与案例详解(文末免费送书)

1、Python编程语言与金融大数据分析 随着信息技术的飞速发展&#xff0c;大数据分析技术应运而生&#xff0c;为各行各业带来了前所未有的变革。金融行业作为全球经济的核心&#xff0c;对数据十分依赖。因此&#xff0c;掌握大数据分析技术对于金融从业者来说具有重要的现实意…

易泊车牌识别相机:4S 店的智能之选

在当今数字化时代&#xff0c;科技的进步不断为各个行业带来更高效、便捷的解决方案。对于 4S 店来说&#xff0c;易泊车牌识别相机的出现&#xff0c;无疑为其运营管理带来了全新的变革。 一、易泊车牌识别相机的强大功能 易泊车牌识别相机以其卓越的性能和精准的识别能力&…

Docker平台搭建方法

Docker平台搭建方法 1.1在VMware中创建两个虚拟机&#xff0c;只需要1个网卡&#xff0c;连接192.168.200.0网络。 虚拟机分配2个CPU,2G内存&#xff0c;60G硬盘&#xff0c;主机名分别为server和client,IP地址分别为192.168.200.137和192.168.200.138。server节点还兼做regis…

云计算在教育领域的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 云计算在教育领域的应用 云计算在教育领域的应用 云计算在教育领域的应用 引言 云计算概述 定义与原理 发展历程 云计算的关键技…

紫光展锐携手上赞随身Wi-Fi,让5G触手可及

近年来&#xff0c;随着各类移动应用层出不穷&#xff0c;人们对随时随地上网的需求日益增强&#xff0c;随身 Wi-Fi 设备以其便捷性、灵活性和相对较低的成本&#xff0c;成为用户满足办公、社交、娱乐等多元化需求的重要工具。5G技术的逐步普及为随身Wi-Fi市场注入了新的活力…

Spring资源加载模块,原来XML就这,活该被注解踩在脚下 手写Spring第六篇了

这一篇让我想起来学习 Spring 的时&#xff0c;被 XML 支配的恐惧。明明是写Java&#xff0c;为啥要搞个XML呢&#xff1f;大佬们永远不知道&#xff0c;我认为最难的是 XML 头&#xff0c;但凡 Spring 用 JSON来做配置文件&#xff0c;Java 界都有可能再诞生一个扛把子。 <…

【C++】AVL树的了解和简单实现

目录 AVL树的概念 AVL树介绍 平衡因子 AVL树的插入 平衡因子的更新 【1】平衡因子为0 【2】平衡因子为1/-1 【3】平衡因子为2/-2 选择的处理 旋转的原则 右单旋 具体的三种情况&#xff1a; ​编辑 所有情况的概念图&#xff1a; 对于父亲指针的处理 &…

使用 PageHelper 在 Spring Boot 项目中实现分页查询

目录 前言1. 项目环境配置1.1 添加 PageHelper 依赖1.2 数据库和 MyBatis 配置 2. 统一的分页响应类3. 使用 PageHelper 实现分页查询3.1 Service 层分页查询实现3.2 PageHelper 分页注意事项 4. 控制层调用示例5. 常见问题与解决方案5.1 java.util.ArrayList cannot be cast t…