数据结构与算法---串

博客主要介绍串匹配算法,串指字符串,算法用于查找模式串在文本串中的位置。详细阐述了蛮力算法的两种实现思路及优化方法,还介绍了KMP算法,对比了蛮力与KMP,指出KMP利用此前比较内容可跳过多个,通过next表实现。

串(Sequence)

这里的串是指字符串:由若干个字符组成的有限序列

在这里插入图片描述

串匹配算法

查找一个模式串(pattern)在文本串(text)中的位置
比如:

String text = "Hello World";
String pattern = "or";
text.indexOf(pattern);//7
text.indexOf("other");//-1

几个经典的串匹配算法
蛮力
KMP
Boyer-Moore
Karp-Rabin
Sunday

tlen = text的长度
plen = pattern的长度


蛮力(Brute Force)

顾名思义,就是一个一个比较匹配:以字符为单位,从左到右移动模式串(需要查找比较的字符串),直到匹配成功。

在这里插入图片描述

蛮力算法有2种常见的实现思路

蛮力1

在这里插入图片描述
在这里插入图片描述

pi的取值范围[0, plen)
ti的取值范围[0, tlen)

如果patternChars[pi] == textChars[ti],则
pi++;
ti++;
去比较下一个

如果patternChars[pi] != textChars[ti],则
ti = ti - (pi - 1);//先做减法,再赋值pi=0,别反了
pi = 0;//从0开始计算

如果pi == plen
代表匹配成功

public class BruteForce01 {
	public static void main(String[] args)
	{
		System.out.println(indexOf("Hello World", "or"));
		System.out.println(indexOf("Hello World", "ww"));
	}
	
	public static int indexOf(String text, String pattern)
	{
		if(text == null || pattern == null) return -1;
		int tlen = text.length();
		int plen = pattern.length();
		if (tlen == 0 || plen == 0 || tlen < plen) return -1;
		
		char[] textChars = text.toCharArray();
		char[] patternChars = pattern.toCharArray();
		
		int pi = 0;
		int ti = 0;
		while (pi < plen && ti < tlen) {
			if (textChars[ti] == patternChars[pi]) {
				ti++;
				pi++;
			}else {
				ti = ti - (pi - 1);
				pi = 0;
			}
		}
		return pi == plen ? ti - pi : -1;
	}
}

蛮力1-优化

在发现模式串大于tlen - ti,说明待比较的text比模式串小,说明找不到了,比较就可以结束
在这里插入图片描述
只需要 ti < tlen修改为 ti - pi < tlen - plen;即可


蛮力2

ti是指每一轮比较中Text首个比较字符的位置

在这里插入图片描述

在这里插入图片描述
pi的取值范围[0, plen)
ti的取值范围[0, tlen - plen]

匹配失败
pi = 0;
ti++;

pi == plen
匹配成功


KMP

KMP是1977年,被三个人K某、M某、P某发布

蛮力 VS KMP

在这里插入图片描述
KMP对比蛮力,KMP利用了此前比较过的内容,可以一下跳过好几个

如何办到呢?

KMP有一个next表,该表是根据模式串/需要对比的串的内容生成的一张next表(一般是个数组)

假如生成的表如下:
在这里插入图片描述
在这里插入图片描述
假如匹配到E和D,两者不同,那么pi = next[pi]
也就是pi = next[7] = 3
向右移动的距离是:pi - next[pi] = 7 - next[7] = 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值