Hello 算法 1.0.0b1 C++版。 在正式介绍算法之前,我想告诉你一件有趣的事:其实,你在过去已经学会了很多算法,并且已经习惯将它们 应用到日常生活中。接下来,我将介绍两个具体例子来佐证。 例一:拼积木。一套积木,除了有许多部件之外,还会附送详细的拼装说明书。我们按照说明书上一步步操作, 即可拼出复杂的积木模型。 如果从数据结构与算法的角度看,大大小小的「积木」就是数据结构,而「拼装说明书」上的一系列步骤就是 算法。 独立于编程语言,即可用多种语言实现。 1.2.2. 数据结构定义 「数据结构 Data Structure」是在计算机中组织与存储数据的方式。为了提高数据存储和操作性能,数据结构 的设计原则有: ‧ 空间占用尽可能小,节省计算机内存。 ‧ 数据操作尽量快,包括数据访问、添加、删除、更新等。 1. 引言 hello‑algo.com 10 ‧ 提供简洁的数据表示和逻辑信息,以便算法高效运行。 数据结构的设计 定的误导性。反之,「最差时间复杂度」最为实用,因为它给出了一个“效率安全值”,让我们 可以放心地使用算法。 从上述示例可以看出,最差或最佳时间复杂度只出现在“特殊分布的数据”中,这些情况的出现概率往往很 小,因此并不能最真实地反映算法运行效率。相对地,「平均时间复杂度」可以体现算法在随机输入数据下的 运行效率,用 Θ 记号(Theta Notation)来表示。 对于部分算法,我们可以简单地推算出随0 码力 | 187 页 | 14.71 MB | 1 年前3
Hello 算法 1.0.0b2 C++版。 在正式介绍算法之前,我想告诉你一件有趣的事:其实,你在过去已经学会了很多算法,并且已经习惯将它们 应用到日常生活中。接下来,我将介绍两个具体例子来佐证。 例一:拼积木。一套积木,除了有许多部件之外,还会附送详细的拼装说明书。我们按照说明书上一步步操作, 即可拼出复杂的积木模型。 如果从数据结构与算法的角度看,大大小小的「积木」就是数据结构,而「拼装说明书」上的一系列步骤就是 算法。 独立于编程语言,即可用多种语言实现。 1.2.2. 数据结构定义 「数据结构 Data Structure」是在计算机中组织与存储数据的方式。为了提高数据存储和操作性能,数据结构 的设计原则有: ‧ 空间占用尽可能小,节省计算机内存。 ‧ 数据操作尽量快,包括数据访问、添加、删除、更新等。 1. 引言 hello‑algo.com 10 ‧ 提供简洁的数据表示和逻辑信息,以便算法高效运行。 数据结构的设计 定的误导性。反之,「最差时间复杂度」最为实用,因为它给出了一个“效率安全值”,让我们 可以放心地使用算法。 从上述示例可以看出,最差或最佳时间复杂度只出现在“特殊分布的数据”中,这些情况的出现概率往往很 小,因此并不能最真实地反映算法运行效率。相对地,「平均时间复杂度」可以体现算法在随机输入数据下的 运行效率,用 Θ 记号(Theta Notation)来表示。 对于部分算法,我们可以简单地推算出随0 码力 | 197 页 | 15.72 MB | 1 年前3
Hello 算法 1.2.0 繁体中文 C++ 版技藝、到解放生產力的工業產品、再到宇宙運行的科學規律,幾乎每一件平凡或令人驚嘆的事物背後,都隱 藏著精妙的演算法思想。 同樣,資料結構無處不在:大到社會網絡,小到地鐵路線,許多系統都可以建模為“圖”;大到一個國家,小 到一個家庭,社會的主要組織形式呈現出“樹”的特徵;冬天的衣服就像“堆疊”,最先穿上的最後才能脫下; 羽毛球筒則如同“佇列”,一端放入、一端取出;字典就像一個“雜湊表”,能夠快速查找目標詞條。 . 2 0.2 如何使用本書 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 0.3 小結 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 第 1 章 初識演算法 11 1.2 演算法是什麼 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.3 小結 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 第 2 章 複雜度分析0 码力 | 379 页 | 18.79 MB | 10 月前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器函数在读取的时候抛出异常,写入的时候又默默创建 。 • 例如:一个同学问小彭老师在干嘛? • 小彭老师说“我在吃答辩。”那么同学认为这个答辩指的是三体动画,小彭老师在看三体动画。 而不会认为小彭老师真的在吃答辩。 • 小彭老师说“我在拉答辩。”那么同学认为这个答辩指的是答辩(物理),小彭老师在上厕所。 而不会认为小彭老师在制作三体动画。 • 所以这位同学是人类思维,相当于 Python Python 的精分 API 。而如果另一个同学是硬核的计算 机思维,相当于 C++ 的一视同仁 API ,他会以为小彭老师真的在吃答辩。 • 这是通常来说,不过万一小彭老师真的这么重口味在吃答辩呢?要怎么传达这个信息? C++ 一视同仁的接口就能处理这种罕见的情况,不过 Python 用一些 if 语句套一套一样可以。 深入理解 Python 中 [] 能自动区分是读是写的原理 • 写入要创建元 C++ 不同, Java 放弃了花里胡哨的运算符重载,索性都采用成员函数 get put 来表示,非常明确。主要是为了把 get 和 put 作为接口函数,可以对应多个具体 实现。 错误示范 • 小彭老师说过,读取必须用 at 。 • 而这位同学却用了 [] 来读取 items 里的值。 • 乍看之下好像没错,运行结果也是正确的,但 这只是碰巧你的 items 里存在 “ hello” 而已,0 码力 | 90 页 | 8.76 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 12 从计算机组成原理看 C 语言指针scanf(“%10s”, str); • int size = 1000; • int *arr = (int *)malloc(size); • 如果你没看出来(哪怕是其中一个),那就要好好上小彭老师的课哦! 字节( byte ) 和位( bit )有什么区别 • 众所周知,计算机是二进制的,存储的实际上是一个个 0 和 1 。 • 每个存储 0 或 1 的空间称为一个位( bit ),一位可以存储 65536 字节,那所谓的内存地址实际上就 是一个从 0 到 65535 范围的整数,也就是两个字节组成的字。 • 处理器去读写内存的时候靠的是寄存器提供的地址,因此寄存器的大小(也就是字的大 小)决定了他能读写的内存大小,例如: • 由于 16 位计算机的寄存器只能存储 16 位,他只能访问 65536 字节( 64 KB )的内存 。 • 由于 32 位计算机的寄存器只能存储 32 位,他只能访问 sizeof(T) 获取 T 类型的字节数。 实验:不同大小之间的整数互转 • C 语言可以用 (short)x 的形式来强制把任意类型的 x 转换为 short 类型。 • 如果源类型比目的类型小,那么会根据目的类型是有 符号还是无符号的,自动扩展他的符号位。 • 例如 char 类型的 -128 是 10000000 • 强制转换为 short 后是 11111111 100000000 码力 | 128 页 | 2.95 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化• 冷知识:并行地给浮点数组每个元素做一次加法反而更慢。 • 因为一次浮点加法的计算量和访存的超高延迟相比实在太少了。 • 计算太简单,数据量又大,并行只带来了多线程调度的额外开销 。 • 小彭老师经验公式: 1 次浮点读写 ≈ 8 次浮点加法 • 如果矢量化成功( SSE ): 1 次浮点读写 ≈ 32 次浮点加法 • 如果 CPU 有 4 核且矢量化成功: 1 次浮点读写 ≈ 128 Main RAM read 的时间指的是 读一个缓存行( 64 字节)所花费的时间。 • 根据计算: 125/64*4≈8 • 即从主内存读取一次 float 花费 8 个 cycle , 符合小彭老师的经验公式。 • “right” 和“ wrong” 指的是分支预测是否成功。 多少计算量才算多? • 看右边的 func ,够复杂了吧?也只是勉勉强强超过一 点内存的延迟了,但在 6 个物理核心上并行加速后, 。 1 2 4 6 8 10 0 50 100 150 200 250 300 350 funcA funcB funcC 内存信息查看工具: dmidecode • 可以看到小彭老师电脑上插了 2 块内存,频率都是 2667 MHz ,数据的宽度是 64 位( 8 字节)。 • 理论极限带宽 = 频率 * 宽度 * 数量 2667*16*2=42672 MB/s •0 码力 | 147 页 | 18.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串C++ 系列课:字符与字符串 by 小彭老师( @archibate ) 课件 & 代码: https://github.com/parallel101/course 上期回顾: https://www.bilibili.com/video/BV1m34y157wb 课程安排 1. vector 容器初体验 & 迭代器入门 (BV1qF411T7sd) 2. 你所不知道的 程序收到 ^C 以后,就直接终止退 出了。 关于控制字符的一个冷知识 • 除此之外,因为 ^D 是“传输终止符”,还可以在控制 台输入 Ctrl+D 来关闭标准输入流,终止正在读取他 的程序。 • 小彭老师常用 Ctrl+D 来快速关闭一个 shell (和输入 exit 命令的效果一样)。 • 以及按 Ctrl+I 的效果其实和 Tab 键一样,按 Ctrl+J 的效果和 Enter 键一样,按 namespace std; 太危险了不想用他。 • 可以只用 using namespace std::literials; • 这个特殊的名字空间里包含了所有的 operator“” 函数。 小彭老师锐评:何谓“键盘压力” • 高情商:键盘压力,指的是程序员敲击键盘时产生的心理压力。 • 低情商:键盘压力,指的是 rust 键盘侠对 cpp 标准委员会的压力。 • rust 键盘侠曰:我们有0 码力 | 162 页 | 40.20 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 eatTwice ,就可以对猫和狗都适用,实现代码的复用( dont-repeat-yourself ), 也让函数的作者不必去关注点从猫和狗的其他具体细节,只需把握住他们统一具有的“吃”这个接口。 小知识: shared_ptr 如何深拷贝? 浅拷贝: 深拷贝: 思考:能不能把拷贝构造函数也作为虚函数? • 现在我们的需求有变,不是去对同一个对象调用两次 eatTwice ,而是先把对象复制一份 把对象就地拷贝到另一个地址的对象去。 • 同理还有 move_assign 对应于移动赋值 , move_clone 对应于移动构造,全了! • 就这样把 C++ 的四大特殊函数变成了多 态的虚函数,这就是被小彭老师称为自动 虚克隆 (auto-vitrual-clone) 的大法。 Zeno 中对 OpenVDB 对象的封装 • 开源的体积数据处理库 OpenVDB 中有许多“网格”的类(可以理解为多维数组),例如: • 他们还有一些成员函数,这些函数可能是虚函数,也可能不是。 • 如何在不知道 OpenVDB 每个类具体继承关系的情况下,实现我们想要的继承关系,从而 实现封装和代码重用?简单,只需用一种被小彭老师称为类型擦除 (type-erasure) 的大法 。 类型擦除:还是以猫和狗为例 • 例如右边的猫和狗类,假设这两个类是某个第 三方库里写死的,这个第三方库的作者可能没 上过《面向对象程序设计》,居然没有定义一0 码力 | 54 页 | 3.94 MB | 1 年前3
Hello 算法 1.1.0 C++ 版到解放生产力的工业产品、再到宇宙运行的科学规律,几乎每一件平凡或令人惊叹的事物背后,都隐藏着精 妙的算法思想。 同样,数据结构无处不在:大到社会网络,小到地铁线路,许多系统都可以建模为“图”;大到一个国家,小 到一个家庭,社会的主要组织形式呈现出“树”的特征;冬天的衣服就像“栈”,最先穿上的最后才能脱下; 羽毛球筒则如同“队列”,一端放入、另一端取出;字典就像一个“哈希表”,能够快速查找目标词条。 为渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析。 复杂度分析能够体现算法运行所需的时间和空间资源与输入数据大小之间的关系。它描述了随着输入数据大 小的增加,算法执行所需时间和空间的增长趋势。这个定义有些拗口,我们可以将其分为三个重点来理解。 ‧“时间和空间资源”分别对应时间复杂度(time complexity)和空间复杂度(space complexity)。 当算法程序运行时,正在处理的数据主要存储在内存中。图 3‑2 展示了一个计算机内存条,其中每个黑色方 块都包含一块内存空间。我们可以将内存想象成一个巨大的 Excel 表格,其中每个单元格都可以存储一定大 小的数据。 第 3 章 数据结构 hello‑algo.com 53 系统通过内存地址来访问目标位置的数据。如图 3‑2 所示,计算机根据特定规则为表格中的每个单元格分配 编号,确保每个内存空间都0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.2.0 简体中文 C++ 版到解放生产力的工业产品、再到宇宙运行的科学规律,几乎每一件平凡或令人惊叹的事物背后,都隐藏着精 妙的算法思想。 同样,数据结构无处不在:大到社会网络,小到地铁线路,许多系统都可以建模为“图”;大到一个国家,小 到一个家庭,社会的主要组织形式呈现出“树”的特征;冬天的衣服就像“栈”,最先穿上的最后才能脱下; 羽毛球筒则如同“队列”,一端放入、另一端取出;字典就像一个“哈希表”,能够快速查找目标词条。 为渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析。 复杂度分析能够体现算法运行所需的时间和空间资源与输入数据大小之间的关系。它描述了随着输入数据大 小的增加,算法执行所需时间和空间的增长趋势。这个定义有些拗口,我们可以将其分为三个重点来理解。 ‧“时间和空间资源”分别对应时间复杂度(time complexity)和空间复杂度(space complexity)。 当算法程序运行时,正在处理的数据主要存储在内存中。图 3‑2 展示了一个计算机内存条,其中每个黑色方 块都包含一块内存空间。我们可以将内存想象成一个巨大的 Excel 表格,其中每个单元格都可以存储一定大 小的数据。 第 3 章 数据结构 www.hello‑algo.com 53 系统通过内存地址来访问目标位置的数据。如图 3‑2 所示,计算机根据特定规则为表格中的每个单元格分配 编号,确保每个内0 码力 | 379 页 | 18.48 MB | 10 月前3
共 28 条
- 1
- 2
- 3













