回朔法/KMP算法-查找字符串

  1. 回朔法:在字符串查找的时候最容易想到的是暴力查找,也就是回朔法。其思路是将要寻找的串的每个字符取出,然后按顺序在源串中查找,如果找到则返回true,否则源串索引向后移动一位,再重复查找,直到找到返回true,或者源串查找完也没有找到返回false;这种方法简单粗暴,但思路清晰。又因为每次查找失败,源串需要回到起始位置的下一个位置开始查找,所以该算法也称为回朔法。
  2. KMP算法:先对要查找的字符串进行分析,找出其中重复的子字符串。然后将目标串与源串比较,一旦比较失败,则不用回朔,而是根据目标串子串的重复情况,直接调到重复子串的下一个位置。这样减少了大量的回朔,算法复杂度得意大量减小。

下面代码演示了回朔法和KMP算法,并作测试。

KMP算法查找:

 1 package org.lyk.impl;
 2 
 3 public class KMP<T>
 4 {
 5     public boolean comtains(T[] source, T[] target) throws Exception
 6     {
 7         if(source == null || target == null)
 8         {
 9             throw new Exception("比较目标不能为空");
10         }
11          
12         int sourceLength = source.length;
13         int targetLength = target.length;
14         if(targetLength > sourceLength)
15             //目标串长达大于源串,肯定不存在,直接返回false
16             return false;
17         else if(targetLength == sourceLength)
18         {
19             //两个串长度相等,则挨个比较,若发现任何一个元素不相等,则直接返回false,若所有元素均相等个,则返回true
20             return this.compair(source, target);
21         }
22         else
23         {//源串长度大于目标串长度,用KMP算法比较
24             
25             //分析目标串的重复情况,生成next数组
26             int[] next = this.getNext(target);
27             int currentSourceIndex = 0;
28             int currentTargetIndex = 0;
29             
30             //如果目标串没有到末尾,则继续循环,如果已经到目标串末尾,则说明找到
31             while(currentTargetIndex < targetLength)
32             {
33                 //如果源串下标越界,说明查找结束,乜没有找到结果,返回false
34                 if(currentSourceIndex >= sourceLength)
35                     return false;
36                 
37                 if(source[currentSourceIndex].equals(target[currentTargetIndex]))
38                 {
39                     //两个元素相等,目标串和源串下标向后各移动一位
40                     currentSourceIndex++;
41                     currentTargetIndex++;
42                 }
43                 else
44                 {
45                     
46                     //目标串的第一个元素就与源串不相等,则源串向后移动一个位置继续比较
47                     if(currentTargetIndex == 0)
48                     {
49                         currentSourceIndex++;
50                     }
51                     
52                     currentTargetIndex = next[currentTargetIndex];
53                 }
54             }
55             return true;
56         }
57     }
58     
59     private int[] getNext(T[] target)
60     {
61         int[] next = new int[target.length];
62         if(next.length > 2)
63         {
64             for(int i = 2; i<target.length; i++)
65             {
66                 int count = 0;
67                 for(int j = 0;j < i-1; j++)
68                 {
69                     boolean flag = true;
70                     for(int k = 0; k <= j; k++)
71                     {
72                         if(target[k] != target[i-1-j+k])
73                         {
74                             flag = false;
75                             break;
76                         }
77                     }
78                     if(flag == true)
79                     {
80                         count = j+1;
81                     }
82                 }
83                 next[i] = count;
84             }
85         }
86         return next;
87     }
88     
89     private boolean compair(T[] source, T[]target)
90     {
91         for(int i = 0; i < source.length; i++)
92         {
93             if(!source[i].equals(target))
94                 return false;
95         }
96         return true;
97     }
98 }

 回朔法(暴力比较)查找字符串:

 1 public static boolean strContain_BF(String _source, String _target)
 2     {
 3         boolean retVal = false;
 4         if (null == _source || null == _target || "".equals(_source) || "".equals(_target))
 5             return false;
 6         char[] source = _source.toCharArray();
 7         char[] target = _target.toCharArray();
 8         int sourceLength = source.length;
 9         int targetLength = target.length;
10         if (targetLength > sourceLength)
11             return false;
12         else if (targetLength == sourceLength)
13         {
14             for (int i = 0; i < sourceLength; i++)
15             {
16                 if (source[i] != target[i])
17                     return false;
18             }
19             return true;
20         } else
21         {
22             for (int i = 0; i <= sourceLength - targetLength; i++)
23             {
24                 boolean flag = true;
25                 for (int j = 0; j < targetLength; j++)
26                 {
27                     if (target[j] != source[i + j])
28                     {
29                         flag = false;
30                         break;
31                     }
32                 }
33                 if (flag == true)
34                     return true;
35             }
36             return false;
37         }
38     }
原文地址:https://www.cnblogs.com/kuillldan/p/6037487.html