重新整理数据结构与算法(c#)——KMP破解[二十七]
前言
很多人把KMP和暴力破解分开,其实KMP就是暴力破解,整个高大上的名字,难道还不是去试错匹配吗?
KMP是这样子的,比如说:
绿色部分是我要匹配的。
按照一般写法是这样子的:
ABABA 去匹配 ABABC 发现匹配不了,然后后移一位用BABACDEFG 去匹配 ABABC。
KMP在此做了优化,本来后移一位的,这时候KMP后移两位再去匹配。
那么这个两位是怎么来的呢?
下面是规律:
正文
普通暴力破解:
static void Main(string[] args)
{
string str1 = "不玩德玛西亚之力这可真的不是太好!";
string str2 = "太好";
int index=violenceMatch(str1,str2);
Console.WriteLine(index);
Console.Read();
}
public static int violenceMatch(String str1, String str2)
{
int i = 0;
int j = 0;
while (i<str1.Length&&j<str2.Length)
{
if (str1[i] == str2[j])
{
i++;
j++;
}
else
{
i = i - (j - 1);
j = 0;
}
}
if (j == str2.Length)
{
return i - j;
}
return -1;
}
kmp 暴力破解:
static void Main(string[] args)
{
String str1 = "BBC ABCDAB ABCDABCDABDE";
String str2 = "ABCDABD";
int[] next = kmpNext("ABCDABD");
int index= kmpSearch(str1,str2,next);
Console.WriteLine(index);//15
Console.Read();
}
public static int kmpSearch(string str1, string str2, int[] next)
{
for (int i = 0, j = 0; i < str1.Length; i++)
{
while (j > 0 && str1[i] != str2[j])
{
j = next[j - 1];
}
if (str1[i] == str2[j])
{
j++;
}
if (j == str2.Length)
{
return i - j+1;
}
}
return -1;
}
public static int[] kmpNext(string dest)
{
int[] next = new int[dest.Length];
//如果只有一个那么没有前缀和后缀
next[0] = 0;
for (int i = 1,j=0; i < dest.Length; i++)
{
while (j>0&& dest[i] != dest[j])
{
j = next[j - 1];
}
if (dest[i] == dest[j])
{
j++;
}
next[i] = j;
}
return next;
}