在字符串处理领域,后缀自动机(Suffix Automaton)是一种强大而高效的工具,能够在线性时间内完成多种复杂操作,如子串查询、不同子串计数等。本文将手把手教你使用 Rust语言 实现一个功能完整的后缀自动机,即使你是编程新手也能轻松理解!

后缀自动机是一种有限状态自动机,它能识别给定字符串的所有后缀。更神奇的是,它还能识别该字符串的所有子串!它的核心优势在于:
这些特性使得Rust后缀自动机成为高性能字符串算法中的明星结构。
我们将采用经典的在线增量构建方法。每个状态节点包含以下信息:
len:该状态能表示的最长字符串长度link:后缀链接(suffix link),指向另一个状态next:字符到状态的转移映射下面是一个完整的、可运行的 Rust 后缀自动机实现:
#[derive(Default)]pub struct State { len: usize, link: Option, next: [Option; 26], // 假设只处理小写英文字母}pub struct SuffixAutomaton { states: Vec, last: usize,}impl SuffixAutomaton { pub fn new() -> Self { let mut states = Vec::new(); states.push(State::default()); // 初始状态 Self { states, last: 0 } } pub fn extend(&mut self, c: char) { let c_idx = (c as u8 - b'a') as usize; let cur = self.states.len(); self.states.push(State { len: self.states[self.last].len + 1, link: None, next: Default::default(), }); let mut p = self.last; while p != 0 && self.states[p].next[c_idx].is_none() { self.states[p].next[c_idx] = Some(cur); p = self.states[p].link.unwrap_or(0); } if p == 0 { self.states[cur].link = Some(0); } else { let q = self.states[p].next[c_idx].unwrap(); if self.states[p].len + 1 == self.states[q].len { self.states[cur].link = Some(q); } else { let clone = self.states.len(); self.states.push(State { len: self.states[p].len + 1, link: self.states[q].link, next: self.states[q].next, }); while p != 0 && self.states[p].next[c_idx] == Some(q) { self.states[p].next[c_idx] = Some(clone); p = self.states[p].link.unwrap_or(0); } self.states[q].link = Some(clone); self.states[cur].link = Some(clone); } } self.last = cur; } // 计算不同子串的数量 pub fn count_distinct_substrings(&self) -> usize { let mut total = 0; for i in 1..self.states.len() { total += self.states[i].len - self.states[self.states[i].link.unwrap()].len; } total }}// 使用示例fn main() { let mut sam = SuffixAutomaton::new(); for c in "abcbc".chars() { sam.extend(c); } println!("不同子串数量: {}", sam.count_distinct_substrings());} 让我们逐步理解这段 Rust编程教程 中的核心逻辑:
掌握 后缀自动机实现 后,你可以将其应用于:
通过本教程,你已经掌握了如何用 Rust 从零实现一个功能完整的后缀自动机。这种数据结构虽然初看复杂,但一旦理解其核心思想——状态表示等价类,后缀链接维护后缀关系——就能灵活运用于各种字符串算法场景中。
建议你动手修改代码,尝试支持 Unicode 字符、添加子串查询功能,或优化内存使用。实践是掌握 Rust后缀自动机 的最佳途径!
本文由主机测评网于2025-12-07发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025124393.html