C++ 中的 BK 树2025 年 5 月 15 日 | 阅读 10 分钟 引言BK 树,或称 Burkhard-Keller 树,是一种专为高效近似字符串匹配而设计的数据结构。它特别适用于拼写检查器、自动完成和 DNA 测序等应用,在这些应用中,查找与给定查询相近的单词或序列至关重要。BK 树 能够快速搜索指定编辑距离内的元素,使其成为处理传统精确匹配算法无法满足的大型数据集的理想选择。 问题陈述BK 树解决的主要问题是有效地查找数据集中与查询字符串具有给定编辑距离的所有元素。编辑距离,通常是 Levenshtein 距离,衡量将一个字符串转换为另一个字符串所需的最少单字符编辑(插入、删除或替换)次数。这在信息检索、生物信息学和错误纠正等领域至关重要。 历史BK 树的概念由 **Walter Burkhard** 和 **Robert Keller** 于 1973 年在其题为“某种最佳匹配文件搜索方法”的论文中首次提出。BK 树利用度量空间的性质,特别是三角不等式,来减少查找近似匹配所需的比较次数。 BK 树如何工作?1. 插入
2. 搜索
例如考虑使用字符串“book”、“back”和“books”构建一个 BK 树。首先插入“book”作为根。然后,插入“back”(与“book”距离为 2),创建一个子节点。接下来,插入“books”(与“book”距离为 1),添加另一个子节点。 搜索与“boon”距离为 1 的字符串
示例 1下面是使用 Levenshtein 距离的 C++ BK 树的简单实现 输出 Words within distance 1 from "boon": book 说明
插入复杂度
搜索复杂度
总体复杂度
示例 2让我们举个例子来说明 C++ 中 BK 树的工作原理。 输出 similar words in dictionary for : ops: oops pop Correct words in dictionary for helt: hell help shell fell felt halt 说明
时间复杂度 很明显,时间复杂度主要取决于容差限制。我们将容差限制考虑为 2。现在,粗略估计,BK 树的深度将为 log n,其中 n 是字典的大小。因此,时间复杂度将为 **O(L1*L2*log n)**,其中 L1 是字典中单词的平均长度,L2 是拼写错误的长度。通常,L1 和 L2 会很小。 辅助空间 上述实现的**空间复杂度为 O(L1*L2)**,其中 L1 是字典中的单词数,L2 是单词的最大长度。 结论总之,BK 树,以其发明者 Burkhard 和 Keller 命名,是一种优雅而高效的数据结构,旨在解决近似字符串匹配问题。它在需要检索指定编辑距离内的字符串的应用中表现出色,例如拼写检查、自动完成和生物信息学。 要点回顾
插入和搜索
复杂度
下一主题C++ 中的不区分大小写搜索 |
优化问题在科学、工程和技术领域无处不在。从设计高效的电路到规划运输路线,优化解决方案是一项基本任务,需要强大的算法。然而,许多现实世界的优化问题是非线性的、复杂的,并且充满了局部最优解,这使得...
阅读 13 分钟
引言“星形数”是指一种形数,它表示一个中心化的六角星,一个六角星。这些数字属于更广泛的数字类别,它们在视觉上形成几何图案。第 n 个星形数可以使用特定公式计算,并且...
阅读9分钟
概述 当代 C++ 编程中关于资源管理和对象生命周期的核心思想之一被封装在 C++ 的“零规则”中。它强调编译器生成的特殊成员函数(如构造函数、析构函数、复制构造函数和复制赋值运算符)的版本应该...
7 分钟阅读
引言 在统计学和概率论领域,卡方 (χ²) 分布是一个非常重要的概念,在假设检验、置信区间估计和拟合优度检验中都有应用。在 C++ 中,我们可以通过 std::chi_squared_distribution 类生成服从卡方分布的随机数...
阅读9分钟
在本文中,我们将讨论如何在 C++ 中查找 n 位步进数。在开始编程之前,我们必须了解步进数。什么是步进数?步进数是指其相邻数字排列方式使其...
5 分钟阅读
在面向对象编程中,特别是在 C++ 中,类充当创建对象的蓝图,这些对象封装数据以及对这些数据进行的操作。一个类通常由成员变量(属性)和成员函数(方法)组成,这些成员函数定义了从该类实例化的对象的行为。然而,在...
阅读 15 分钟
在计算机科学领域,特别是在字符串处理和组合学中,不同子序列的概念占有重要地位。子序列是从字符串中删除零个或多个字符而不改变剩余字符的顺序而派生出来的。查找……
阅读 15 分钟
引言 C++ 的获取-释放(acquisition-release)语义对于同步多线程程序至关重要,以保证线程对共享数据的可预测和可重复访问。它是控制并发程序的强大内存排序机制。获取-释放(acquisition-release)语义是内存排序系列的一部分...
阅读 6 分钟
在本文中,我们将通过示例讨论。std::memory_order 函数指定了应围绕原子操作排列的内存访问(包括常规内存访问和非原子内存访问)的顺序。当多个线程同时读写多个变量时,……
阅读 4 分钟
在本文中,我们将研究 C++ 算法,用于打印 Smarandache-Wellin 数列的前 m 项。但是,首先,我们需要了解 Smarandache-Wellin 数列。一系列 Smarandache-Wellin 数称为 Smarandache-Wellin 数列。被称为 Smarandache-Wellin 数的整数是通过连接...
阅读 6 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India