如何理解 python 修饰器原理
引子
在 Python 中有一个非常重要且有特色的语法 修饰器 ,但是修饰器的语法也非常难懂,只有更好的理解修饰器原理才能更好掌握该语法。在网上查了不少资料,但是发现很多文章仅仅介绍了修饰器的基本使用而没有介绍其 原理 ,本文将分从 基本语法 和 实现原理 两个方面谈谈我对修饰器的理解。
基本语法
无参修饰器
123456789101112# 无参修饰器的基本格式def decorator(func): def wrapper(*args, **kwargs): # front operators __ = func(*args, **kwargs) # later operators return __ return wrapper@decoratordef func(*args, **kwargs): pass # do something
下面举个时间测试修饰器的例子:
1234567891011121314151617import timedef time_it(func): def wrap ...
如何理解 C++ 顶层和底层 const 下复杂类型
建站提交历史文章,原文写作时间 2023 年 6 月 15 日。
前言
关于多级指针中的 const 修饰初学者都会觉得是一个很玄学的问题,我也是初学者,在深入理解后在此留下一些自己的理解,使用更多的示例与图示用这篇短文来展示理解的过程。同时也发现在这一块文章也不多,因此希望此文能对你有帮助。
top-level-const :顶层常量,指指针本身是常量。
low-level-const :底层常量,指指针指向的量是常量。
本文将从 const 指针、const 数组指针两个角度带你理解顶层和底层常量修饰。
12 月 17 日更:最近在阅读 C++ Primer 11,其中也非常详细的介绍了顶层和底层 const。(书落实验室不便标注页码)
玄学 const 指针
12345int *p; // 指向变量的指针变量const int *p; // 指向常量的指针变量int const *p; // 等价于 const int *pint * const p; // 指向变量的指针常量const int * c ...
WSL安装方法
参考资料 安装 WSL - Microsoft Learn | WSL (Windows 10) - OI Wiki 加入必坑指南与图文教程
简介
WSL 是从 Windows 10 2004 开始支持的,Microsoft 官方支持的适用于 Linux 的 Windows 子系统 (Windows Subsystem for Linux),开发人员可以安装 Linux 发行版 (例如 Ubuntu、OpenSUSE、Kali、Debian、Arch Linux 等),并直接在 Windows 上使用 Linux 应用程序。可以参阅 WSL 的官方文档。
与传统的虚拟机启动或双系统启动方式相比,由官方支持的 WSL 不仅配置方便,而且无需承担传统方式带来的巨大开销。
自动安装
后面将介绍自动安装和手动安装,两种方式选一即可,建议优先尝试使用自动安装,此处我们以安装 Ubuntu 为例。
打开 Powershell 并且执行下面的命令,一键完成安装。
12wsl --install -d Ubuntu# wsl --list --online # 查看所有可安装的最新发行版本
进入 ...
平衡树&二叉搜索树 - B 树
前往 算竞题解 分类 || 前往 算竞模板 分类
简介
B 树 是多叉搜索平衡树。B 树 的结构更好的满足局部性原理,越矮的树的索引次数越少,从读写上提高代码效率。由于在磁盘访问中,数据读写占据了多数时间,因此 B 树 这种数据结构在数据库系统中有较好的效率。B 树 实际上很少使用,但它是 B+ 树、红黑树 的基础。
模板题链接
洛谷 P3369 【模板】普通平衡树
核心思想
定义: m (m≥3)m~(m \ge 3)m (m≥3) 阶 B 树 的定义为:
满足中序遍历升序。
每个节点最多容纳 m−1m - 1m−1 个键。
每个节点最少容纳 ⌈m2⌉−1\lceil\frac{m}{2}\rceil - 1⌈2m⌉−1 个键,除根节点最少包含 111 个键。
对于所有内部节点,如果节点容纳 kkk 个键,则其有 k+1k + 1k+1 个子节点。
对于所有叶子节点,没有任何子节点。
所有叶子节点必须位于同一层。
时间复杂度:
由于 B 树 保证每个节点至少半满,且所有叶子节点位于同一层,因此树的最大深度是对数的。
中序遍历
1234567891011// 遍历. ...
平衡树&二叉搜索树 - AVL
前往 算竞题解 分类 || 前往 算竞模板 分类
简介
AVL 是最早发明的平衡树,通过旋转维护任意点的左右子树高度差小于 111,从而实现 O(logn)O(\log{n})O(logn) 的时间复杂度。
模板题链接
洛谷 P3369 【模板】普通平衡树
左旋与右旋
维护二叉搜索树平衡,左旋 (zag) 和右旋 (zig) 是其基本操作。
123456 | | | A B A / \ Zig(A) / \ Zag(B) / \ B [3] ========> [1] A ========> B [3] / \ / \ / \[1] [2] [2] [3] [1] [2]
核心思想
二叉搜索树只有在插入和删除节点时才会改变节点 ...
平衡树&二叉搜索树 - 二叉搜索树
前往 算竞题解 分类 || 前往 算竞模板 分类
简介
二叉搜索树(BST)用于快速增删改查数据,对外部可以看作一个集合。BST 的平均时间复杂度是 O(logn)O(\log{n})O(logn),但是遗憾的是其最坏时间复杂度是 O(n)O(n)O(n) 的。为了解决 BST 的这个问题,之后会介绍多种平衡树。平衡树通过不同的维护方式,保证了其始终有 O(logn)O(\log{n})O(logn) 的时间复杂度,BST 是所有平衡树的基础,同时其多数操作在多数平衡树中是通用的。
模板题链接
只有最后一组数据会 TLE。
洛谷 P3369 【模板】普通平衡树
核心思想
定义: 对于一棵有根树的任意节点,如果满足左子树所有节点的权值均小于该节点的权值,且右子树均大于该值,则称之为 BST。即对于任意节点 xxx 有权 max{kl}<k<min{kr}\max\{k_l\} < k < \min\{k_r\}max{kl}<k<min{kr},其中 kkk 表示节点 xxx 的权值,{kl}\{k_l\}{kl} 表示 xxx 左 ...
平衡树&二叉搜索树 - 笛卡尔树
前往 算竞题解 分类 || 前往 算竞模板 分类
简介
下面介绍一种不常用但是经常被提起的数据结构 —— 笛卡尔树,可以说是平衡树的入门基础。
笛卡尔树既满足二叉搜索树又满足堆,即对于任意键值对 {k,v}\{k,v\}{k,v},max{kl}<k<min{kr}\max\{k_l\} < k < \min\{k_r\}max{kl}<k<min{kr} 且 max{vl}≥v≤max{vr}\max\{v_l\} \ge v \le \max\{v_r\}max{vl}≥v≤max{vr},其中 {kl}\{k_l\}{kl} 表示左子树中的所有 kkk。
由于笛卡尔树能解决的问题很多都能通过单调栈解决,因此笛卡尔树很少用。
模板题链接
洛谷 P3369 【模板】普通平衡树
HDU 1506 Largest Rectangle in a Histogram (不止一种解法哦)
核心思想
首先我们需要按 kkk 将键值对排序,假设我们将索引当作 kkk 则序列就是已排序的。从左往右遍历即可 O(n)O(n)O(n) 完成笛卡尔 ...
平衡树&二叉搜索树 - Splay
前往 算竞题解 分类 || 前往 算竞模板 分类
简介
平衡树种类众多,各有优劣,其公共功能是完成 O(logn)O(\log{n})O(logn) 的增删改查。本文将介绍 Splay,其优点是代码短,缺点是常数较大。此外,Splay 还可以处理区间翻转问题。Splay 不属于严格的平衡树,但与平衡树有相同的均摊复杂度。
模板题链接
洛谷 P3369 【模板】普通平衡树
核心思想
Splay 的核心为 splay 也是重要的基本操作,只要在完成任何搜索时通过 splay 操作将搜索到的节点旋转到根 ,即可非常神奇地得到 O(logn)O(\log{n})O(logn) 的时间复杂度。
splay 讨论 666 种情况:zig(右旋)、zag(左旋)、zig-zig、zag-zag、zig-zag、zag-zig。
由于左右对称只需讨论其中 333 种情况:
zig:完成一次右旋,当且仅当父节点为根,否则考虑后面两种情况。
zig-zig:对祖父节点完成一次右旋,再对父节点完成一次右旋。
zig-zag:对父节点完成一次左旋,再对祖父节点完成一次右旋。
代码虽短,涵盖了上述三种 ...
ACMer 一键板子导出工具 cpps2md
前往 小工具指北 分类
这是我的个人开源项目,Github 自取 jamhus-tao/cpps2md,本来是给自己用的,当然也希望帮助更多人。
cpps2md @Jamhus Tao
简介
这是一个 cpp 转 markdown 脚本,主要用于 ACMer 整理板子。如果你不是 ACMer(参与大学生程序设计竞赛的人),这个项目或许对你没有什么帮助。众所周知,ACM 系列赛事允许赛时使用纸质资料,于是每到赛前都需要将之前的练习整理成册打印出来,这是一个繁琐的工作。
通过该工具,你只需要将所有待打印的练习,分门别类地整理到一个文件夹内,运行脚本就可以整理成单一的 Markdown 文件。然后使用你喜欢的方式打印该 Markdown 文件。
本工具为命令行工具,运行窗口简陋,但功能实用。同时支持 .cpp 和 .md 文件格式、支持板子增量式打印。也就是说工具会检测你相较于上一次更改了哪些文件并且只导出它们。
演示
原来的文件夹长这样,其中 .bin 放了我的工具,.out 放了工具导出的文件,其他几个可以无视。
运行脚本导出到 .out 文件夹。
然后我使用 Typora 将它 ...
Github + Hexo + Butterfly 建站笔记(六) - 自定义配置
回到文章目录
修改配置文件
众所周知,网站即 html + css + js,通过修改 css 和 js 我们可以自定义配置我们的主题。
首先修改配置文件,这里建议将需要的所有内容添加到 /css/my.css 和 /js/my.js 。
12345678910# Inject# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)# 插入代码到头部 </head> 之前 和 底部 </body> 之前inject: head: # - <link rel="stylesheet" href="/xxx.css"> - <link rel="stylesheet" href="/css/my.css"> bottom: # - <script src=& ...