重新整理数据结构与算法(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;
}
posted @ 2020-07-17 16:40  敖毛毛  阅读(202)  评论(0编辑  收藏  举报