10分钟搞懂Sunday算法:比KMP更易上手的字符串匹配技巧
【免费下载链接】Learn-Algorithms 算法学习笔记 项目地址: https://gitcode.com/gh_mirrors/le/Learn-Algorithms
在日常编程中,你是否曾为字符串查找效率低下而困扰?当面对日志分析、关键词过滤等场景时,如何快速从海量文本中定位目标字符串?本文将介绍一种比KMP算法更简单易懂的字符串匹配算法——Sunday算法,带你轻松掌握高效字符串查找技巧。
什么是字符串匹配
字符串匹配(String Matching)是在一段文本(主串)中查找另一段字符串(模式串)出现位置的过程。这是编程中最基础也最常用的操作之一,广泛应用于文本编辑器、搜索引擎、数据处理等领域。
项目中已介绍的KMP算法通过预处理模式串构建部分匹配表来优化匹配过程,而Sunday算法则采用了更直观的后移策略,实现了类似的效率提升但更易于理解和实现。
Sunday算法核心思想
Sunday算法由Daniel M.Sunday于1990年提出,其核心创新点在于匹配失败时的后移规则:当主串与模式串不匹配时,算法会关注主串中位于模式串后方的下一个字符(即"关注字符"),并根据该字符在模式串中的位置决定后移步数。
匹配步骤
- 从主串和模式串的起始位置开始比较
- 若当前字符匹配,则继续比较下一个字符
- 若不匹配:
- 查看主串中模式串长度位置的下一个字符c
- 若c在模式串中存在,后移步数 = 模式串长度 - c在模式串中最右出现的位置
- 若c不在模式串中,后移步数 = 模式串长度 + 1
- 重复上述步骤直至找到匹配或到达主串末尾
实例演示
假设我们要在主串"HERE IS A SIMPLE EXAMPLE"中查找模式串"EXAMPLE":
初始状态:
主串: H E R E I S A S I M P L E E X A M P L E
模式串: E X A M P L E
↑
不匹配,关注字符是主串中模式串后一位的空格
空格不在模式串中,后移7+1=8位:
主串: H E R E I S A S I M P L E E X A M P L E
↓
模式串: E X A M P L E
↑
匹配成功
算法实现要点
核心数据结构
Sunday算法的关键是坏字符表(Bad Character Table),用于存储每个字符在模式串中最右侧出现的位置:
void build_bad_char_table(char *pattern, int m, int *bad_char) {
// 初始化所有字符位置为-1
for (int i = 0; i < 256; i++) {
bad_char[i] = -1;
}
// 记录每个字符最后出现的位置
for (int i = 0; i < m; i++) {
bad_char[(unsigned char)pattern[i]] = i;
}
}
匹配函数实现
int sunday_search(char *text, int n, char *pattern, int m, int *bad_char) {
int i = 0; // text的起始索引
while (i <= n - m) {
int j;
// 从模式串尾部开始匹配
for (j = m - 1; j >= 0 && text[i + j] == pattern[j]; j--);
if (j < 0) {
// 找到匹配
return i;
}
// 计算后移步数
int next_char_index = i + m;
if (next_char_index < n) {
unsigned char c = text[next_char_index];
i += (m - bad_char[c]);
} else {
// 超出文本范围
break;
}
}
return -1; // 未找到匹配
}
性能分析
时间复杂度
- 最佳情况:O(n/m),当模式串在主串中频繁出现时
- 平均情况:O(n)
- 最坏情况:O(n*m),但实际应用中很少出现
空间复杂度
- O(1),仅需固定大小的坏字符表(通常为256个字符)
与其他算法对比
| 算法 | 预处理时间 | 匹配时间 | 空间复杂度 | 实现难度 |
|---|---|---|---|---|
| 暴力匹配 | O(0) | O(n*m) | O(1) | 简单 |
| KMP算法 | O(m) | O(n) | O(m) | 较复杂 |
| Sunday算法 | O(m) | O(n) | O(1) | 简单 |
Sunday算法在保持线性时间复杂度的同时,具有实现简单和实际应用中效率高的特点,尤其适合处理短模式串和文本编辑场景。
项目中的应用
在本项目中,字符串匹配相关内容主要集中在1 String/目录下,其中KMP.md详细介绍了经典的KMP算法。虽然目前项目中没有专门的Sunday算法实现文件,但在9 Algorithms Job Interview/1 字符串.md和9 Algorithms Job Interview/codes/1 string/目录中,提供了多种字符串处理相关的代码实现,包括:
- char_first_appear_once.c:查找字符串中第一个只出现一次的字符
- replce_blank.c:替换字符串中的空格
- revert_by_word.c:单词翻转
总结与实践建议
Sunday算法以其简洁的思想和高效的性能,成为字符串匹配领域的优秀选择。对于初学者,建议:
- 先理解暴力匹配的局限性,再学习Sunday算法的优化思路
- 手动模拟算法执行过程,加深对后移规则的理解
- 实现基础版本后,尝试优化坏字符表的构建方式
- 通过9 Algorithms Job Interview/目录中的题目进行实践练习
掌握字符串匹配算法不仅能帮助你解决实际编程问题,更能培养你的算法思维。在README.md中,你可以找到更多算法学习资源和项目结构说明,开始你的算法学习之旅吧!
【免费下载链接】Learn-Algorithms 算法学习笔记 项目地址: https://gitcode.com/gh_mirrors/le/Learn-Algorithms
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



