编程奇境:C++之旅,从新手村到ACM/OI算法竞赛大门(铠甲:STL)

2024-06-14 01:04

本文主要是介绍编程奇境:C++之旅,从新手村到ACM/OI算法竞赛大门(铠甲:STL),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这个充满数据结构的世界,C++已经封装了很多迅速可用的数据结构。这就像我们身上的铠甲,不管遇到什么样的怪物,都能靠着这套铠甲防御攻击。


动态数组vector

想象一下,在奇幻的世界里,有一个神奇的魔法背包,名叫vector,它来自强大的编程魔法——STL(标准模板库)。这个背包拥有三大神奇特性:

  1. 自动伸缩的魔法:不像普通的背包空间固定,vector背包能根据你放置物品的多少自动调整大小。当你往里面放入更多的宝物时,它会悄无声息地变大,仿佛内部有着无限的空间;而当你取出宝物,它又能灵巧地收缩,始终保持紧致,既不浪费空间,也不让你感到负担。

  2. 快速取用的秘诀:在vector背包里,每件宝物都有自己的位置编号,就像你在图书馆书架上按序摆放的书籍。无论何时,只要你报出编号,背包就能瞬间为你取出对应的宝物,这种直接访问的魔法让探险旅途更加顺畅。

  3. 有序排列的智慧:虽然vector背包里的空间可以随意扩展,但所有的宝物都严格按照放入的顺序整齐排列,无论是新增还是移除,都不会打乱原有的秩序,确保你随时掌握宝物的最新排列情况。

  4. 与魔法世界的兼容:这个背包不仅与各种宝物(数据类型)兼容,还能无缝对接其他魔法工具(STL算法和容器),让探险者(程序员)能够轻松组合出强大的魔法技能,解决旅途中的种种难题。

综上所述,vector不仅是探险者可靠的伙伴,更是编程世界里的一项基础而又强大的神器,它以其独特的灵活性、高效性和通用性,成为了无数编程冒险旅程中的首选装备。

#include<bits/stdc++.h>
using namespace std;int main()
{vector<int> a;//<>里放的是数据类型 a.push_back(1);//push_back是放入的函数 a.push_back(5);cout<<a[0]<<endl;//按下标输出 for(auto i:a)//循环遍历输出 {cout<<i<<endl;}vector<string> s;s.push_back("xx");for(string i='a';i<='z';i++){s.push_back(i);}for(auto k:s){cout<<k<<endl;}return 0;
}

集合set 

想象一下,在一个充满奇幻色彩的王国里,有一个特别的魔法宝盒,名叫set。这个宝盒非常神奇,它不仅能够自动整理收纳进来的宝物,确保每个宝物都是独一无二的,而且还能够按照一定的魔法法则自动排序,让宝物井然有序。

宝物收纳与去重

每当勇士从冒险中带回新的宝物,只要轻轻一扔进set宝盒,宝盒就会施展它的魔力:如果盒内已经有了同样的宝物,它就会拒绝接纳,确保每个种类的宝物只保留一件,完美实现了自动去重的效果。这样一来,不管收集了多少宝物,盒子里始终保持着每件宝物的独特性。

自动排序

更令人称奇的是,set宝盒内部似乎有一本隐形的魔法书,上面记载着一套排序咒语。每当有新宝物加入,宝盒会立刻按照这本书上的规则,自动将新宝物放到合适的位置,确保所有宝物都按照一定的顺序排列。这样一来,不论何时打开宝盒,里面的宝物总是整齐划一,便于勇士快速找到他想要的那一件。

只可观摩,不可篡改

不过,这个宝盒有个特别的规定:一旦宝物被妥善安置,就不允许勇士直接从中取出宝物进行修改后再放回。宝物一旦被收纳,就如同被施加了保护咒,只能整件取出或者整件替换,保证了宝盒内宝物序列的稳定和纯净。

魔法探索

在编程的世界里,set就是这样一个数据结构,它来自于强大的STL(标准模板库)。开发者可以用它来存储唯一且有序的数据,比如存储不重复的用户ID、整理去重的单词列表等。通过简单的插入、删除和查找操作,set就能帮助我们高效地管理这些数据,就像是一个自动分类和过滤的神奇宝盒,让代码的世界也充满了秩序和效率。

#include<bits/stdc++.h>
using namespace std;int main()
{set<int> a;//set会自动去重 且 自动从小到大排序 a.insert(1);//insert是插入函数 a.insert(5);a.insert(4);a.insert(6);a.insert(1);for(auto k:a){cout<<k<<endl;} return 0;
}

map

想象你是一位探险家,手握一张古老而神奇的藏宝图,这张图就是map——编程世界里的宝藏定位器。与普通地图不同,这张藏宝图不仅标出了宝藏的位置,还为每个宝藏配上了独一无二的秘密钥匙,让每一次寻宝之旅都精准而高效。

宝藏与钥匙的约定

在这张藏宝图上,每个宝藏(value)都被精确绑定到一把特定的钥匙(key)上。钥匙可以是任何独特的东西,比如一个数字、一段文字或者一个符号,每个钥匙都指向地图上的唯一一个宝藏。这意味着,当你手持正确的钥匙,就能够立即找到对应的宝藏,无需翻遍整个地图。

寻宝之旅

  • 添加宝藏:如果你发现了新的宝藏,只需将这宝藏连同其专属钥匙一起记录在地图上,map会自动帮你归档,确保下次能迅速找回。

  • 探索宝藏:想查看某个特定钥匙所对应的宝藏,只需轻轻一点,map瞬间展示出藏宝地点,无需遍历整个藏宝图。

  • 更新秘密:如果某处宝藏的位置发生了变化,或者你想更换宝藏,只要提供正确的钥匙,就可以直接替换或更新该处的宝藏信息。

  • 抹去痕迹:若决定放弃某个宝藏,只需告诉map对应的钥匙,它就会永久抹去那份记录,确保藏宝图永远是最新的。

魔法的秩序

更令人惊叹的是,这张藏宝图自动保持着所有钥匙的有序排列,无论是字母顺序、数字大小,或是你自定义的规则,它都能迅速响应,让你在浩瀚的信息中迅速定位,无论是查找、增添还是删除,都如同施展了一场迅速而精确的魔法。

#include <bits/stdc++.h>
using namespace std;int main() {// 创建一个魔法字典,键是咒语名,值是魔法效果描述map<string, string> spellbook;// 放入咒语及其效果spellbook["Lumos"] = "发出亮光照亮四周";       // 添加照明咒spellbook["Wingardium Leviosa"] = "使物体漂浮"; // 添加漂浮咒// 输出特定咒语的效果cout << spellbook["Lumos"] << endl; // 输出: 发出亮光照亮四周// 遍历魔法字典,展示所有咒语及其效果for(auto entry : spellbook) {cout << "咒语: " << entry.first << ", 效果: " << entry.second << endl;}// 创建另一个魔法字典,这次关联字母与该字母在魔法字母表中的位置map<char, int> magicalAlphabet;// 初始化字母表for(char letter = 'a'; letter <= 'z'; ++letter) {magicalAlphabet[letter] = letter - 'a' + 1; // 计算位置}// 输出魔法字母表for(auto entry : magicalAlphabet) {cout << "字母: " << entry.first << ", 位置: " << entry.second << endl;}return 0;
}

栈stack

想象你正置身于一个古老而神秘的图书馆深处,那里藏有一本无尽之书,名为stack。这本魔法书与众不同,它遵循着“后进先出”的古老法则,记录着一系列珍贵的知识和秘密。

知识的叠加

在这个图书馆里,每位学者都小心翼翼地向这本无尽之书《stack》中添加新的篇章。有趣的是,每次添加新页,都会自动置于书的最上方,就像堆叠起的盘子,最新放置的总是在最顶端,最下方的则是最早放置的。这便是stack的核心奥义——“后进先出”(LIFO, Last In First Out)原则。

探索与揭示

  • 压栈:每当有新的发现或灵感闪现,学者们便使用push这个魔法词语,将新知识轻轻一推,它便神奇地出现在书的最顶层,成为当前最亟待探索的内容。

  • 弹栈:而想要回顾最近一次添加的内容,只需轻轻一声pop,最上方的页面便会自动分离,展露出其下的秘密,而这份知识也随之离开了《stack》,回到了学者的记忆之中。

  • 窥视顶页:如果只是好奇而不急于揭开,top法术能让最上层的知识显露一角,供人一窥究竟,而不会改变书的堆叠顺序。

  • 检测空满:随着时间流逝,学者们还能通过emptysize两种探测魔法,了解书是否已满载知识,或是空空如也,等待新的填充。

生活中的隐喻

在编程的世界中,stack就如同那个神秘图书馆中的无尽之书,它帮助我们管理那些需要遵循特定顺序处理的数据,比如函数调用的顺序、撤销操作的历史记录、浏览器的后退按钮等。每当有新的操作发生,就像在书中添加新的一页;而当需要回溯时,最近的操作被最先处理,恰似学者翻阅书页,探求最近的记忆。

#include<bits/stdc++.h>
using namespace std;int main()
{stack<int> st;st.push(1);//入栈 st.pop();//出栈 cout<<st.size()<<endl;//栈的大小 while(!st.empty())//判断栈不为空时 {cout<<st.top()<<endl;//输出栈顶 st.pop();}return 0;
}

 队列queue

信使的守则

队列遵循着“先进先出”(First In, First Out, FIFO)的古老法则。这意味着最早到达队列的包裹,将最先被送达,正如清晨的露珠等候阳光的亲吻,排在首位的旅客期待着第一缕阳光的照耀。

魔法包裹的旅程

  • 入队:每当新的包裹来到,魔法使只需轻声一句“enqueue”,包裹便自动加入队列的末尾,融入那条光河之中,静候它的旅程。

  • 出队:而在队列的另一端,最前面的包裹在“dequeue”的咒语下,化作一道光芒,飞向它的目的地,同时为后面的包裹腾出了前进的空间。

  • 窥视队首:若想知晓即将出发的是哪份包裹,只需施展“peek”法术,便能在不扰乱队列秩序的情况下,一睹其风采。

  • 检查队列:用“is_empty”或“size”咒语,可快速了解队列是否空空如也,或是包裹数量几何,这对于管理这条魔法通道至关重要。

队列的魔力应用

在魔法与现实交织的世界里,队列的形态千变万化:

  • 魔法师的助手:在繁忙的魔法学院,学员提交的作业通过队列有序等待批改,保证了每位学生都能及时得到反馈。

  • 传送门的守卫:在多维旅行的传送门旁,旅客们排成队列,按顺序穿越,维持了时空旅行的稳定与安全。

  • 咒语的编织:复杂的咒语组合中,每个咒词依序通过队列等待释放,确保魔法仪式的精准执行。

#include<bits/stdc++.h>
using namespace std;int main()
{queue<int> q;q.push(1);//入队 q.pop();//出队 cout<<q.size()<<endl;//队列大小 while(!q.empty())//队列不为空时 {cout<<q.front()<<endl;//输出队列头 q.pop();} return 0;
}

练习题 

B3614 【模板】栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

B3616 【模板】队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P3370 【模板】字符串哈希 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P5250 【深基17.例5】木材仓库 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P5266 【深基17.例6】学籍管理 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P3613 【深基15.例2】寄包柜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P4387 【深基15.习9】验证栈序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

L1-079 天梯赛的善良 - 团体程序设计天梯赛-练习集 (pintia.cn)

L1-080 乘法口诀数列 - 团体程序设计天梯赛-练习集 (pintia.cn)

L2-002 链表去重 - 团体程序设计天梯赛-练习集 (pintia.cn)

L2-014 列车调度 - 团体程序设计天梯赛-练习集 (pintia.cn)

百看不如一练,只有实践才是进步最快的方式,更要独立思考,如果想不出来了就看题解,会有眼前一亮的感觉。好啦,今天就到这里吧。下一期再见,记得给专栏点个关注,明天接着来哦~

这篇关于编程奇境:C++之旅,从新手村到ACM/OI算法竞赛大门(铠甲:STL)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1058937

相关文章

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解