字符串匹配小结
来源:互联网 发布:mac收藏网页 编辑:程序博客网 时间:2024/06/01 13:24
字符串匹配小结
- 字符串匹配小结
- 声明
- 字符串匹配问题
- OnmOncdot m时间复杂度暴力匹配
- OnmOnm复杂度Rarbin-Karp算法
- 1 Rarbin-Karp算法思想
- 2 实现注意点说明
- 2 代码实现
声明
文章均为本人技术笔记,转载请注明出处:
[1] https://segmentfault.com/u/yzwall
[2] blog.csdn.net/j_dark/
字符串匹配问题
问题描述:对于一个给定的 source 字符串和一个target字符串,你应该在source字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。
source
串长度设为target
串长度设为
1 O(n⋅m) 时间复杂度:暴力匹配
- lintcode strstr,该题目不要求时间复杂度优化到
O(n⋅m) ;
class Solution { public int strStr(String source, String target) { if (source == null || target == null) { return -1; } int n = source.length(); int m = target.length(); if (m == 0) { return 0; } int i, j; for (i = 0; i <= n - m; i++) { for (j = 0; j < m; j++) { if (source.charAt(i + j) != target.charAt(j)) { break; } } if (j == m) { return i; } } return -1; }}
2 O(n+m) 复杂度:Rarbin-Karp算法
- lintcode strStrⅡ,该题目要求时间复杂度优化到
O(n+m) ;
2.1 Rarbin-Karp算法思想
暴力匹配的时间开销source
串每个字符开头的子串是否匹配,Rabin-Karp算法的思想是用尽量一一对应的散列值去代表每个字符串,有推论:
+ 推论一:hashcode
不相等的字符串字面值必然不同;
+ 推论二:hashcode
相同的字符串,因为哈希冲突无法避免,可能字面值不同,需要继续进行一一字符检查;
优化效果:通过计算字符串的hashcode
,将字符串字符挨个比较的时间开销O(m)优化到比较hashcode
的时间开销
2.2 实现注意点说明
在实际运算中,极容易发生整数溢出bug,因此需要不断进行模运算,选取任意大数取模时应注意不易过大;
2.2 代码实现
散列函数参考java.lang.String
类,假定有字符串target
,字面值为
实现步骤:
1. 预处理:计算target
串的散列值targetCode
和
2. 扫描source
串:维护扫描窗口大小为hashcode
,并与targetCode
相比较
如果二者不相等,根据推论一,扫描窗口向后移动一个字符,新的hashcode
需要减去刚被移出扫描窗口的上一个字符
如果二者相等,继续比较字面值是否相同;
public class Solution { public int strStr2(String source, String target) { if (source == null || target == null) { return -1; } int n = source.length(); int m = target.length(); if (m == 0) { return 0; } int mod = 1000000; int targetCode = 0; int power = 1; for (int i = 0; i < m; i++) { targetCode = (targetCode * 31 + target.charAt(i)) % mod; power = (power * 31) % mod; } int hashCode = 0; for (int i = 0; i < n; i++) { hashCode = (hashCode * 31 + source.charAt(i)) % mod; if (i < m - 1) { continue; } if (i >= m) { hashCode = (hashCode - source.charAt(i - m) * power) % mod; // 防止负数溢出 if (hashCode < 0) { hashCode += mod; } } if (hashCode == targetCode) { if (source.substring(i - m + 1, i + 1).equals(target)) { return i - m + 1; } } } return -1; }}
- 字符串匹配小结
- 字符串模式匹配算法小结
- Lua字符串模式匹配函数小结
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配...
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- 字符串匹配
- WinDbg-如何抓取dump文件
- 文件系统(2)
- zhihu-spider开源项目的README.md
- C语言的单字符IO之getchar()和putchar()
- 高考机器人首秀未答满分 人工智能未知大于已知
- 字符串匹配小结
- 线程的控制
- 打造Android万能上拉下拉刷新框架--XRefreshView(三)
- Mybatis学习(4):Mybatis及PageHelper插件和easyUI实现分页
- Vim插件之vimwiki
- 人工智能实现简单的五子棋程序
- 决策树实现
- Reverse Singly LinkedList的方法探讨
- 在ssh中用struts2标签读取list数组集合