问题:
现在有两个字符串A和B,A中有B,有多少??
其实我第一次遇到这个问题的时候,还以为挺简单的!循环过去一探究竟就够了,当然这样做也行
可以实现,而且编程简单粗暴,两个周期就可以解决。但是这种方法的时间复杂度是O(M*N),
M是字符串A的大小,N是字符串B的大小,所以时间复杂度太高,我们需要低时间复杂度
算法,于是就诞生了KMP算法,该算法的时间复杂度为O(M+N)。
KMP算法的基本原理
算法的第一步是创建下一个数组。这个数组有什么用,后面会解释。下一个数组代表字符串B的前面
后缀和后缀的最大数量相等,这是什么意思?? 举个例子。
假设 A = "baab"
乙=""
对于第一个i数,假设i=4,字符串“abaa”的前缀是“a”、“ab”、“aba”;后缀为“a”、“aa”、“baa”,其中
有一组前缀和后缀相同的字符串java字符串匹配度算法,就是“a”,所以同一个字符串的最大字符数是1,所以next[i-1=3]=1(
该组从0开始计数,所以这里是i-1); 根据这个规则,我们可以写数组 B ,5} 的 next={0,0,1,1,2,0,1,2,3,4};
算法的第二步是使用字符串 B 将字符串 A 逐步向右移动。在 A 中移动的位置用 j 表示,在 B 中移动的位置是
用k表示,上面的例子就是用来解释这个算法的。当j=0,k=0时,字符串A中的'a'和字符串B中的'a'这两个字符相同。
等等,然后是 j++;k++; j=1,k=1java字符串匹配度算法,字符串A的'b'和字符串B的'b'两个字符相等,继续j++,k++;等等
当推到i=5,j=5时,A字符串的'a'和B字符串的'b'这两个字符不相等。此时j=next[j-1]=2,继续放A数组
第 i 个字符串与 B 数组的第 j 个字符串进行比较。此时A串的i=5为'a',B串j=2(此时j的值已经出现。
改)'a'的值,两个字符串相同,则i++,j++;此时A字符串的数组为'a',B字符串的数组为'a',重复
重复上述过程。最后,当 i 的值等于 A 字符串的长度时,循环结束。这里要注意的一件事是,在比较字符时
模板字符总是不相等的。例如,如果上例 i=5 中遇到的字符不是 'a',而是 'c',那么 j=2 的字符也不相等。
那么 j=next[j-1]=0; 当 j=0 时,字符不等于 'c'。如果不处理这种情况,就会发生溢出,所以
因为我们需要处理它。当我们的j=0仍然不等于第i个字符时,我们应该跳过这个字符串,即i++;
这在编程时尤其重要。
介绍完算法的全过程后,我们来分析一下它的可行性,为什么要用它来生成next数组?? 这个号码
小组做什么?? 如果不考虑算法层面,只从数学层面做这道题,就要比较首字母
比较,然后在第 6 个字符处中断,然后你会立即从第 4 个字符开始比较,你这样做的原则是字符串
A的第六个字符的前两个字符和字符串B的前两个字符是一样的,所以我们选择第四个字符开始,接下来你会想
数组生成的原理,你有发现吗??
我们在第6个字符处打断,表示A和B的前5个字符相同,next5-1表示前缀和后缀最多
相同数量的字符串,这次是 2。这意味着 B 字符串中的第 1 和第 2 个字符必须等于 A 数组中的第 4 和第 5 个字符。
如果是这样,我们只需要直接比较 B 数组的第三个元素和 A 数组的第六个元素。现在知道下一个数组
有用!!!
以下是我为算法写的c代码算法的时间复杂度为O,这个数组有啥用?
,仅供参考,如有错误请指教:
<p><pre>1#include"stdio.h"
2#include"string.h"
3#include"malloc.h"
4#define N 20 //定义字符串模板长度
5#define N1 50 //定义需要匹配的字符串的长度
6int get_array(char B); //得到next数组
7void main()
8{
9 char B[N]="aba"; //定义模板字符串
10 char A[N1]="abaabaabbabaaabaabbabaab"; //定义需要匹配的字符串
11 int *next; //定义next数组
12 int i=0,j=0,flag=0;
13 next=(int )malloc(strlen(B)sizeof(int)); //给next数组开辟空间
14 next=get_array(B); //得到next数组的值
15 while(i0) //防止一个字符一直找不到匹配导致溢出
16 {
17 j=next[j-1];
18 }
19 else //如果有一个字符一直找不到匹配,则进行下一个字符重新匹配
20 {
21 i++;
22 j=0;
23 }
24
25 }
26 }
27 if(flag) //判断是否存在该模板字符串
28 {
29 printf("exist the number and exist number is %d ",flag);
30 }
31 else
32 {
33 printf("not exist the number");
34 }
35 getchar();
36
37}
38int get_array(char B)
39{
40 int L=strlen(B); //L代表模板字符串的长度
41 int key=0; //用来记录前缀和后缀相同的数目
42 int *next; //找到前缀和后缀相同的数目最大值
43 next=(int )malloc(Lsizeof(int));
44 for(int i=0;i