LeetCode Implement strStr(kmp或者BM)
2016-07-27 18:17
302 查看
题意:求一字符串在另一字符串的中的索引
思路:kmp
代码如下:
解法二
解法三:bm算法
思路:kmp
代码如下:
public class Solution { private int[] kmp_table(String s) { int[] next = new int[s.length()]; next[0] = -1; for (int i = 1; i < s.length(); i++) { int j = next[i - 1]; while (j > -1 && s.charAt(j) != s.charAt(i - 1)) { j = next[j]; } next[i] = j + 1; } return next; } private int kmp_search(String text, String pattern) { int[] next = kmp_table(pattern); int match_start = 0, pattern_start = 0; while (match_start + pattern_start < text.length()) { while (match_start + pattern_start < text.length() && text.charAt(match_start + pattern_start) == pattern.charAt(pattern_start)) { if (++pattern_start == pattern.length()) return match_start; } match_start += pattern_start - next[pattern_start]; pattern_start = next[pattern_start] > -1 ? next[pattern_start] : 0; } return -1; } public int strStr(String haystack, String needle) { if (haystack.compareTo(needle) == 0) return 0; if (needle.isEmpty()) return 0; if (haystack.length() < needle.length()) return -1; return kmp_search(haystack, needle); } }
解法二
public class Solution { private int[] kmp_table(String s) { int[] next = new int[s.length()]; next[0] = -1; int j = -1, i = 0; while (i < s.length()) { while (j > -1 && s.charAt(j) != s.charAt(i)) { j = next[j]; } j++; i++; if (i < s.length() && j < s.length()) { if (s.charAt(i) == s.charAt(j)) { next[i] = next[j]; } else { next[i] = j; } } } return next; } private int kmp_search(String text, String pattern) { int[] next = kmp_table(pattern); int match_start = 0, pattern_start = 0; while (match_start < text.length()) { while (pattern_start > -1 && text.charAt(match_start) != pattern.charAt(pattern_start)) { pattern_start = next[pattern_start]; } pattern_start++; match_start++; if (pattern_start == pattern.length()) { return match_start - pattern_start; } } return -1; } public int strStr(String haystack, String needle) { if (haystack.compareTo(needle) == 0) return 0; if (needle.isEmpty()) return 0; if (haystack.length() < needle.length()) return -1; return kmp_search(haystack, needle); } }
解法三:bm算法
public class Solution { private Map<Character, Integer> skip_; private int[] suffix_; private void build_skip_table(String s) { skip_ = new HashMap<>(); for (int i = 0; i < s.length(); i++) { skip_.put(s.charAt(i), i); } } private int[] compute_bm_prefix(String s) { if (s.length() == 0) return null; int[] prefix = new int[s.length()]; prefix[0] = 0; int k = 0; for (int i = 1; i < s.length(); i++) { while (k > 0 && s.charAt(k) != s.charAt(i)) { k = prefix[k - 1]; } if (s.charAt(k) == s.charAt(i)) k++; prefix[i] = k; } return prefix; } private void build_suffix_table(String s) { if (s.length() == 0) return ; int[] prefix = compute_bm_prefix(s); String reverse_s = new StringBuilder(s).reverse().toString(); int[] reverse_prefix = compute_bm_prefix(reverse_s); suffix_ = new int[s.length() + 1]; for (int i = 0; i <= s.length(); i++) { suffix_[i] = s.length() - prefix[s.length() - 1]; } for (int i = 0; i < reverse_s.length(); i++) { int index = reverse_s.length() - reverse_prefix[i]; int shift = i - reverse_prefix[i] + 1; if (suffix_[index] > shift) { suffix_[index] = shift; } } } private int do_search(String text, String pattern) { build_skip_table(pattern); build_suffix_table(pattern); int index_end = text.length() - pattern.length(); int i = 0; while (i <= index_end) { int j = pattern.length(); while (text.charAt(i + j - 1) == pattern.charAt(j - 1)) { j--; if (j == 0) return i; } int k = skip_.containsKey(text.charAt(j - 1)) ? skip_.get(pattern.charAt(j - 1)) : -1; int m = j - 1 - k; if (k < j && m > suffix_[j]) { i += m; } else { i += suffix_[j]; } } return -1; } public int strStr(String haystack, String needle) { if (haystack.compareTo(needle) == 0) return 0; if (needle.isEmpty()) return 0; if (haystack.length() < needle.length()) return -1; return do_search(haystack, needle); } }
相关文章推荐
- ZooKeeper实战应用之【统一配置管理】
- C语言实现md5函数代码
- libqr--简单好用的c++二维码生成库
- tortoisegit 保存用户名密码
- hihocoder Popular Products(STL)
- MongoDB的局域网连接问题
- 虚拟机打包重新部署全过程详细说明
- mysql存储过程初级
- 显示Intent和隐式Intent的使用(意图)
- Ant自动编译Java project时无法找到rt.jar的处理方法
- c# 导出excel 组件比较(npoi vs openxml)
- 1026 逃跑的拉尔夫
- 粘人的小泥块源代码
- vi常用命令
- 鸭子应用--策略模式
- XStream xml to bean
- 编写类似strcmp() strncmp()函数
- 第一个JNI例子
- java 和c#泛型
- CGI和Servlet的对比