字符串的模式匹配问题

针对字符串的模式匹配问题,解决的算法有挺多的,下面就把我所知道的一一介绍吧。

第一种,朴素模式匹配(时间复杂度为O(mn))

之所以把这种算法称作朴素模式匹配,我想大概是因为这个算法可以看做是在通过遍历,从而完成匹配,这种方式应该是比较朴素的。(个人看法)

举例来说吧。

主串s = “abcdabcde”,子串t = “abcde”

(1)从主串第一个字符开始,和子串中的字符进行逐一比较,可以发现前四个字符都匹配成功,而第四个没有匹配成功;

(2)主串的开始下标+1,然后再继续跟子串匹配(子串从0下标开始);



(3)没有匹配成功,就重复第二步,直到全部匹配成功,或者说主串s已到达末尾。




实现代码:

		private static int simple(String s, String t) {
		int i = 0;// 记录主串下标
		int j = 0;// 记录子串下标


		while (i < s.length() && j < t.length()) {


			if (s.charAt(i) == t.charAt(j)) {


				// 当前位置字符匹配成功
				i++;// 主串下标+1
				j++;// 子串下标+1


			} else {


				// 当前位置字符匹配不成功
				i = i - j + 1;//i-j:主串回到匹配初始位置,+1:主串下标+1
				j = 0;// 子串下标置零


			}
		}
		// 匹配成功,返回模式串p在文本串s中的位置,否则返回-1
		if (j == t.length())
			return i - j;
		else
			return -1;
	}

第二种,快速模式匹配(时间复杂度为O(n))

快速模式匹配算法,实现了保持主串的检索位置不懂,而移动子串的检索位置,省去了一些不必要的操作,提高了效率。而要想确定子串的检索位置应该怎么移动,就需要了解几个概念:前缀、后缀。举个例子来说吧,给定字符串“ABCDABD”,

也就是说,原模式串子串对应的各个前缀后缀的公共元素的最大长度表为:


这个表其实就是next数组的前身,把表中数据都往后移一位,并在首位填上-1,即:


其实整个KMP算法的实现,我觉得关键就在于如何获得next数组,next数组其实就是查找模式串中每一位前面的子串的前后缀有多少位匹配,从而决定在失配时子串检索位置应该回退到哪个位置,那接下来就来推敲一下,如何获得next数组吧。

由于我个人的表达能力有限,建议参考http://www.cnblogs.com/tangzhengyue/p/4315393.html,讲的很清楚,通俗易懂。

代码实现:

public static int[] getNext(String t) {

		int[] next = new int[t.length()];

		next[0] = -1;

		int j = 0;

		int k = -1;

		while (j < t.length() - 1) {
			if (k == -1 || t.charAt(j) == t.charAt(k)) {

				next[++j] = ++k;
			} else {

				k = next[k];
			}
		}

		return next;
	}

	public static int KMP(String s, String t) {

		int i = 0;
		int j = 0;

		int[] next = getNext(t);

		while (i < s.length() && j < t.length()) {

			if (j == -1 || s.charAt(i) == t.charAt(j)) { // 当j为-1时,要移动的是i,当然j也要归0

				i++;
				j++;
			} else {
				// i不需要回溯了

				j = next[j]; // j回到指定位置
			}
		}
		
		if (j == t.length()) {

			return i - j;

		} else {

			return -1;

		}
	}
第三种,Boyer-Moore 算法,简称 BM 算法。

BM 算法定义了两个规则:

  • 坏字符规则:当文本串中的某个字符跟模式串的某个字符不匹配时,我们称文本串中的这个失配字符为坏字符,此时模式串需要向右移动,移动的位数 = 坏字符在模式串中的位置 - 坏字符在模式串中最右出现的位置。此外,如果"坏字符"不包含在模式串之中,则最右出现位置为 -1。
  • 好后缀规则:当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为 -1。
第四种,Sunday算法。
Sunday 算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。
  • 如果该字符没有在模式串中出现则直接跳过,即移动位数 = 匹配串长度 + 1;
  • 否则,其移动位数 = 模式串中最右端的该字符到末尾的距离 +1。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有关病毒方面课程的实验内容 实验一 PE结构分析及DOS病毒感染与清除 一、实验目的 1.熟悉PE文件结构 2.掌握DOS系统下.EXE文件病毒感染与清除方法 二、实验要求 1.实验之前认真准备,编写好源程序。 2.实验中认真调试程序,对运行结果进行分析,注意程序的正确性和健壮性的验证。 3.不断积累程序的调试方法。 三、实验内容 1)手工或编程从user32.dll中获得MessageBoxA的函数地址; 2)查阅资料,结合第2章内容,根据PE结构编写一个小的工具软件,或者用PE Explorer、PEditor、Stud_PE等工具软件查看、分析PE文件格式。针对PE文件格式,请思考:Win32病毒感染PE文件,须对该文件作哪些修改; 3)示例病毒exe_v感染原理及其清除 实验二 Windows病毒分析与防治 一、实验目的 掌握Windows病毒感染与清除方法 二、实验要求 1.实验之前认真准备,编写好源程序。 2.实验中认真调试程序,对运行结果进行分析,注意程序的正确性和健壮性的验证。 3.不断积累程序的调试方法。 三、实验内容 1)编程实现Immunity病毒; 2)修复被Immunity感染的host_pe.exe 3)编程实现脚本病毒或宏病毒,参考相关章节爱虫/梅丽莎病毒;修复被上述病毒感染的系统 实验三 蠕虫/木马的分析与防治 一、实验目的 掌握蠕虫/木马感染与清除方法 二、实验要求 1.实验之前认真准备,编写好源程序。 2.实验中认真调试程序,对运行结果进行分析,注意程序的正确性和健壮性的验证。 3.不断积累程序的调试方法。 三、实验内容 1)实现“冲击着清除者”病毒; 2)实现远程线程动态嵌入技术的木马并验证; 3)实现木马远程监视/控制; 4)修复被上述病毒感染的系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值