后缀树简介-Pattern Searching | Set 8 (Suffix Tree Introduction)

本文深入探讨了后缀树的构建方法及其在文本模式搜索、最长重复子字符串查找、最长公共子字符串查找、字符串最长回文等领域的应用。通过实例解析后缀树如何高效地预处理文本,进而实现快速模式搜索,同时介绍了后缀树在解决实际问题中的优势。

原文:http://www.geeksforgeeks.org/pattern-searching-set-8-suffix-tree-introduction/

给定一个文本(字符串)txt[1..n-1] 和一个模式(待搜索字符串)pat[0..m-1],写一个函数search(char pat[], char txt[]),功能是打印出pat[]在txt[]中所有出现的位置。假设 n>m

解决方法:预处理模式还是预处理文本?

一下这些算法是比较经典的解决这个问题的算法:

KMP Algorithm

Rabin Karp Algorithm

Finite Automata based Algorithm

Boyer Moore Algorithm

上述的算法都是预处理模式用以加速搜索的过程。通过这种方法得到的最优时间复杂度为O(n),这里n是文本的长度。在这篇文章里,我们介绍一个预处理文本的方法。后缀树就是根据文本建立的。预处理文本后(建立文本的后缀树),我们可以在O(m)的时间内搜索任意的模式,这里m是模式的长度。

设想你存储了莎士比亚全集并且进行了预处理。你就可以在全集中搜索任意的字符串,而且用时仅与字符串的长度相关。这是一个很大的进步,因为一般情况下模式的长度远低于文本的长度。但是如果文本经常变化,预处理文本的代价就会加大。这种方法对固定的或者变动很少的文本很适合。

后缀树是一种压缩的由给定文本的所有后缀构成的trie树(字典树)。我们介绍过标准trie树。通过下面的字符串数组,让我们了解一下压缩trie树。

{bear, bell, bid, bull, buy, sell, stock, stop}

下图是由上述字符串数组构建的标准trie树:


下图是压缩的trie树。压缩trie树是由标准trie树将一些单个节点组合成链而转换来的。压缩trie树的节点可以通过存储节点的索引范围来表示。

对于一个给定的文本,如何构建后缀树(Suffix Tree)?

通过上述讨论,我们知道了后缀树是由文本的所有后缀组成的压缩tire树。下面是一个构造后缀树的非常抽象的步骤。

1)对给定的文本生成它的所有后缀

2)将所有后缀当做单个字符串来构建压缩trie树。

我们用文本“banana\0”来做个例子,这里“\0”是字符串的终止字符。下面的字符串是“banana\0”的所有后缀:

banana\0

anana\0

nana\0

ana\0

na\0

a\0

\0

假如我们将上述的所有后缀当做单个字符串来构建trie树的话,我们得到了如下图所示的trie树:


如果我们将单个的节点组合成串,我们得到了如下的压缩trie树,这就是文本“banana\0”的后缀树。


注意上述步骤只是人工创建后缀树的过程。我们会分几章来讨论真正的算法和实现过程。

在后缀树中如何搜索模式?

在上面的文字中我们讨论了如何构建后缀树,即模式搜索过程的预处理步骤。下面是在后缀树中搜索模式的抽象步骤。

1)从模式的第一个字符和后缀树的跟节点开始,对每一个字符做如下操作。

......a)对模式中当前的字符,如果在后缀树中当前的节点有一条边,沿着这条边向前。

......b)如果没有边,打印“模式在该文本中不存在”并返回。

2)如果模式中所有的字符都被处理了,即对给定的模式,从后缀树的根存在一条路径,这条路径上的字母组成的字符串与模式相同,那么打印“模式找到”。

我们用模式“nan”作为例子,看看搜索的过程。下图给出了搜索“nan”或者“nana”的路径。


这个方法为什么会有效?

每个文本中可以搜索到的模式(或者说文本的每个子字符串)一定是所有可能的后缀字符串的一个前缀。这个表述貌似有点复杂,但其实内容很简单,你只需要用一些例子验证一下就行。

后缀树的应用

后缀树可以用来解决很多问题。下面是一些比较著名的问题,在这些问题中后缀树都给出了最优时间复杂度的方案。

1)模式搜索

2)查找最长重复子字符串

3)查找最长公共子字符串

4)查找字符串的最长回文

后缀树还有很多其他的应用,详细请看维基百科:http://en.wikipedia.org/wiki/Suffix_tree#Functionality


多源动态最优潮流的分布鲁棒优化方法(IEEE118节点)(Matlab代码实现)内容概要:本文介绍了基于Matlab代码实现的多源动态最优潮流的分布鲁棒优化方法,适用于IEEE118节点电力系统。该方法结合两阶段鲁棒模型与确定性模型,旨在应对电力系统中多源输入(如可再生能源)的不确定性,提升系统运行的安全性与经济性。文中详细阐述了分布鲁棒优化的建模思路,包括不确定性集合的构建、目标函数的设计以及约束条件的处理,并通过Matlab编程实现算法求解,提供了完整的仿真流程与结果分析。此外,文档还列举了大量相关电力系统优化研究案例,涵盖微电网调度、电动汽车集群并网、需求响应、储能配置等多个方向,展示了其在实际工程中的广泛应用价值。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源系统优化工作的工程师。; 使用场景及目标:①用于研究高比例可再生能源接入背景下电力系统的动态最优潮流问题;②支撑科研工作中对分布鲁棒优化模型的复现与改进;③为电力系统调度、规划及运行决策提供理论支持与仿真工具。; 阅读建议:建议读者结合提供的Matlab代码与IEEE118节点系统参数进行实操演练,深入理解分布鲁棒优化的建模逻辑与求解过程,同时可参考文中提及的其他优化案例拓展研究思路。
### 解决 'Unable to write: No space left on device (28)' 错误 此错误表明磁盘空间不足,导致无法写入数据。可通过以下方法解决: - **清理磁盘空间**:删除不再需要的文件,例如日志文件、临时文件、旧的备份等。可以使用系统自带的磁盘清理工具,或者手动删除一些大文件。在Linux系统中,可以使用`du`和`df`命令来查找和清理大文件。例如,使用`du -sh /*`查看各个目录的大小,然后删除不必要的大文件。 ```bash du -sh /* ``` - **扩展磁盘容量**:如果磁盘空间确实不够用,可以考虑扩展磁盘容量。对于云服务器,可以增加磁盘大小;对于本地服务器,可以更换更大容量的硬盘。 - **调整存储位置**:将数据存储到其他有足够空间的磁盘或分区。可以修改RunUMAP函数的输出路径,指向有足够空间的位置。 ### 解决 'search_k/n_trees settings were unable to find 30 neighbors for all items' 错误 该错误意味着UMAP算法在当前的`search_k`和`n_trees`设置下,无法为所有数据点找到30个邻居。可以尝试以下解决方法: - **调整`search_k`和`n_trees`参数**:增大`search_k`和`n_trees`的值,以增加搜索的范围和深度,提高找到邻居的概率。例如: ```python import umap import numpy as np # 示例数据 data = np.random.rand(100, 10) # 调整search_k和n_trees参数 umap_model = umap.UMAP(n_neighbors=30, search_k=500, n_trees=20) transformed_data = umap_model.fit_transform(data) ``` - **检查数据质量**:确保输入的数据没有缺失值或异常值。可以对数据进行预处理,如去除缺失值、标准化数据等。 ```python import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler # 示例数据 data = pd.DataFrame(np.random.rand(100, 10)) # 去除缺失值 data = data.dropna() # 标准化数据 scaler = StandardScaler() scaled_data = scaler.fit_transform(data) ``` - **增加数据量**:如果数据量过少,可能无法找到足够的邻居。可以尝试增加数据量,或者使用数据增强技术来扩充数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值