- 回朔法:在字符串查找的时候最容易想到的是暴力查找,也就是回朔法。其思路是将要寻找的串的每个字符取出,然后按顺序在源串中查找,如果找到则返回true,否则源串索引向后移动一位,再重复查找,直到找到返回true,或者源串查找完也没有找到返回false;这种方法简单粗暴,但思路清晰。又因为每次查找失败,源串需要回到起始位置的下一个位置开始查找,所以该算法也称为回朔法。
- KMP算法:先对要查找的字符串进行分析,找出其中重复的子字符串。然后将目标串与源串比较,一旦比较失败,则不用回朔,而是根据目标串子串的重复情况,直接调到重复子串的下一个位置。这样减少了大量的回朔,算法复杂度得意大量减小。
下面代码演示了回朔法和KMP算法,并作测试。
package org.lyk.main; import org.lyk.entities.List; public class Main { public static void main(String[] args) { String _source = "hello how are you"; String _target = "ello how yo"; System.out.println(_source); System.out.println(_target); System.out.println(strContain_BF(_source, _target)); System.out.println(strContains_KMP(_source, _target)); } public static boolean strContains_KMP(String _source, String _target) { boolean retVal = false; if(null == _source || null == _target || "".equals(_source) || "".equals(_target)) return false; char[] source = _source.toCharArray(); char[] target = _target.toCharArray(); int sourceLength = source.length; int targetLength = target.length; if(targetLength > sourceLength) return false; else if(targetLength == sourceLength) { for(int i = 0; i < sourceLength; i++) { if(source[i] != target[i]) return false; } return true; } else { int[] next = getNext(target); int currentSourceIndex = 0; int currentTargetIndex = 0; while(currentTargetIndex < targetLength) { int k = 0; boolean flag = true; for(int i = currentTargetIndex; i<targetLength; i++) { if((currentSourceIndex + k) >= sourceLength) { return false; } if(target[i] == source[currentSourceIndex+k]) { k++; continue; } else { flag = false; if(i == 0) { currentSourceIndex++; } else { currentSourceIndex = currentSourceIndex + k; } currentTargetIndex = next[currentTargetIndex]; break; } } if(flag == true) return true; } return true; } } public static int[] getNext(char[] target) { int targetLength = target.length; int[] next = new int[targetLength]; if(targetLength <= 2) { for(int i = 0; i< targetLength; i++) { next[i] = 0; } return next; } else { next[0] = 0; next[1] = 0; for(int i = 2; i<targetLength; i++) { int count = 0; for(int j = 0; j < i-1;j++) { boolean flag = true; for(int k = 0; k <=j; k++) { if(target[k] != target[i-1-j+k]) flag = false; } if(flag == true) count = j+1; } next[i] = count; } return next; } } public static boolean strContain_BF(String _source,String _target) { boolean retVal = false; if(null == _source || null == _target || "".equals(_source) || "".equals(_target)) return false; char[] source = _source.toCharArray(); char[] target = _target.toCharArray(); int sourceLength = source.length; int targetLength = target.length; if(targetLength > sourceLength) return false; else if(targetLength == sourceLength) { for(int i = 0; i < sourceLength; i++) { if(source[i] != target[i]) return false; } return true; } else { for(int i = 0; i <= sourceLength - targetLength;i++) { boolean flag = true; for(int j = 0; j < targetLength; j++) { if(target[j] != source[i+j]) { flag = false; break; } } if(flag == true) return true; } return false; } } }
时间: 2024-10-12 13:42:13