最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java暴力匹配及KMP算法解決字符串匹配問題示例詳解

 更新時(shí)間:2021年11月24日 14:27:09   作者:威斯布魯克.猩猩  
這篇文章主要為大家介紹了java算法中暴力匹配算法及KMP算法解決字符串匹配的問題示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

要解決的問題?

一、暴力匹配算法

一個(gè)圖例介紹KMP算法

String str1 = "BBC ABCDAB ABCDABCDABDE";
String str2 = "ABCDABD";

? ??1.?S[0]為B,P[0]為A,不匹配,執(zhí)行第②條指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,S[1]跟P[0]匹配,相當(dāng)于模式串要往右移動(dòng)一位(i=1,j=0)

??2. S[1]跟P[0]還是不匹配,繼續(xù)執(zhí)行第②條指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,S[2]跟P[0]匹配(i=2,j=0),從而模式串不斷的向右移動(dòng)一位(不斷的執(zhí)行“令i = i - (j - 1),j = 0”,i從2變到4,j一直為0)?

?3. 直到S[4]跟P[0]匹配成功(i=4,j=0),此時(shí)按照上面的暴力匹配算法的思路,轉(zhuǎn)而執(zhí)行第①條指令:“如果當(dāng)前字符匹配成功(即S[i] == P[j]),則i++,j++”,可得S[i]為S[5],P[j]為P[1],即接下來S[5]跟P[1]匹配(i=5,j=1)

??4. S[5]跟P[1]匹配成功,繼續(xù)執(zhí)行第①條指令:“如果當(dāng)前字符匹配成功(即S[i] == P[j]),則i++,j++”,得到S[6]跟P[2]匹配(i=6,j=2),如此進(jìn)行下去

?5. 直到S[10]為空格字符,P[6]為字符D(i=10,j=6),因?yàn)椴黄ヅ?,重新?zhí)行第②條指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,相當(dāng)于S[5]跟P[0]匹配(i=5,j=0)?

??6. 至此,我們可以看到,如果按照暴力匹配算法的思路,盡管之前文本串和模式串已經(jīng)分別匹配到了S[9]、P[5],但因?yàn)镾[10]跟P[6]不匹配,所以文本串回溯到S[5],模式串回溯到P[0],從而讓S[5]跟P[0]匹配。?

而S[5]肯定跟P[0]失配。為什么呢?因?yàn)樵谥暗?步匹配中,我們已經(jīng)得知S[5] = P[1] = B,而P[0] = A,即P[1] != P[0],故S[5]必定不等于P[0],所以回溯過去必然會(huì)導(dǎo)致失配。那有沒有一種算法,讓i 不往回退,只需要移動(dòng)j 即可呢?

答案是肯定的。這種算法就是KMP算法,它利用之前已經(jīng)部分匹配這個(gè)有效信息,保持i 不回溯,通過修改j 的位置,讓模式串盡量地移動(dòng)到有效的位置。

public class ViolenceMatch {
	public static void main(String[] args) {
		String str1 = "硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好";
		String str2 = "尚硅谷你尚硅你";
		int index = violenceMatch(str1, str2);
		System.out.println("index=" + index);
	}
	/**
	 * 暴力匹配算法
	 */
	public static int violenceMatch(String str1, String str2) {
		char[] s1 = str1.toCharArray();
		char[] s2 = str2.toCharArray();
 
		int s1Len = s1.length;
		int s2Len = s2.length;
 
		int i = 0;// i索引指向s1
		int j = 0;// j索引指向s2
		while (i < s1Len && j < s2Len) {// 保證匹配時(shí),不越界
			if (s1[i] == s2[j]) {// 匹配ok
				i++;
				j++;
			} else {// 沒有匹配成功
					// 如果不匹配(即str1[i] != str2[j],令i = i - (j - 1),j = 0)
				i = i - (j - 1);
				j = 0;
			}
		}
		// 判斷是否匹配成功
		if (j == s2Len) {
			return i - j;
		} else {
			return -1;
		}
	}
}

暴力匹配算法的缺點(diǎn):大量數(shù)據(jù)使用暴力匹配效率很低

二、KMP算法

關(guān)于KMP算法的學(xué)習(xí),參考了這篇文章,此博主寫的特別詳細(xì),大佬!

參考鏈接:https://www.cnblogs.com/zzuuoo666/p/9028287.html

算法介紹

KMP的主要思想是:1. 先得到子串的部分匹配表 2.使用部分匹配表完成KMP匹配?

一個(gè)圖例介紹KMP算法?

?代碼實(shí)現(xiàn)

public class KMPAlgorithm {
	public static void main(String[] args) {
		String str1 = "BBC ABCDAB ABCDABCDABDE";
		String str2 = "ABCDABD";
		int[] next = kmpNext("ABCDABD");
		System.out.println("next=" + Arrays.toString(next));
 		int index = kmpSearch(str1, str2, next);
		System.out.println("index=" + index);
	} 
	/**
	 * kmp搜索算法
	 * 
	 * @param str1 原字符串
	 * @param str2 子串
	 * @param next 部分匹配表,是子串對(duì)應(yīng)的部分匹配表
	 * @return 如果是-1就是沒有匹配到,否則返回第一個(gè)匹配的位置
	 */
	public static int kmpSearch(String str1, String str2, int[] next) {
		// 遍歷
		for (int i = 0, j = 0; i < str1.length(); i++) {
 
			// 需要處理 str1.charAt(i) != str2.charAt(j),去調(diào)整j的大小
			// KMP算法核心點(diǎn)
			while (j > 0 && str1.charAt(i) != str2.charAt(j)) {
				j = next[j - 1];
			}
			if (str1.charAt(i) == str2.charAt(j)) {
				j++;
			}
			if (j == str2.length()) {// 找到了
				return i - j + 1;
			}
		}
		return -1;
	} 
	/**
	 * 獲取到一個(gè)字符串(子串)的部分匹配值表
	 */
	public static int[] kmpNext(String dest) {
		// 創(chuàng)建一個(gè)next數(shù)組保存部分匹配值
		int[] next = new int[dest.length()];
		next[0] = 0;// 如果字符串是長(zhǎng)度為1部分匹配值就是0
		for (int i = 1, j = 0; i < dest.length(); i++) {
			// 當(dāng)dest.charAt(i) != dest.charAt(j),需要從next[j - 1]獲取新的j
			// 直到發(fā)現(xiàn)有dest.charAt(i) == dest.charAt(j)成立才退出
			// 這是kmp算法核心點(diǎn)
			while (j > 0 && dest.charAt(i) != dest.charAt(j)) {
				j = next[j - 1];
			}
			if (dest.charAt(i) == dest.charAt(j)) {
				j++;
			}
			next[i] = j;
		}
		return next;
	}
}

以上就是java暴力匹配及KMP算法解決字符串匹配問題示例詳解的詳細(xì)內(nèi)容,更多關(guān)于暴力匹配及KMP算法解決字符串匹配的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot整合netty實(shí)現(xiàn)心跳檢測(cè)和自動(dòng)重連

    springboot整合netty實(shí)現(xiàn)心跳檢測(cè)和自動(dòng)重連

    本文主要介紹了Spring Boot中整合Netty實(shí)現(xiàn)心跳檢測(cè)和自動(dòng)重連,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • MyBatis discriminator標(biāo)簽原理實(shí)例解析

    MyBatis discriminator標(biāo)簽原理實(shí)例解析

    這篇文章主要為大家介紹了MyBatis discriminator標(biāo)簽實(shí)現(xiàn)原理實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java實(shí)現(xiàn)Http工具類的封裝操作示例

    Java實(shí)現(xiàn)Http工具類的封裝操作示例

    這篇文章主要介紹了Java實(shí)現(xiàn)Http工具類的封裝操作,涉及java針對(duì)http請(qǐng)求與響應(yīng)、遠(yuǎn)程交互與字符串拼接等操作封裝技巧,需要的朋友可以參考下
    2018-01-01
  • 深入理解Java注解的使用方法

    深入理解Java注解的使用方法

    這篇文章主要為大家詳細(xì)介紹了Java注解的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • SpringBoot集成RabbitMQ和概念介紹

    SpringBoot集成RabbitMQ和概念介紹

    這篇文章主要介紹了SpringBoot集成RabbitMQ和概念介紹,RabbitMQ即一個(gè)消息隊(duì)列,主要是用來實(shí)現(xiàn)應(yīng)用程序的異步和解耦,同時(shí)也能起到消息緩沖,消息分發(fā)的作用。更多相關(guān)內(nèi)容需要的小伙伴可以參考一下下面文章內(nèi)容
    2022-05-05
  • PowerJob的ServerDiscoveryService工作流程源碼解讀

    PowerJob的ServerDiscoveryService工作流程源碼解讀

    這篇文章主要為大家介紹了PowerJob的ServerDiscoveryService工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Springcloud eureka搭建高可用集群過程圖解

    Springcloud eureka搭建高可用集群過程圖解

    這篇文章主要介紹了Springcloud eureka搭建高可用集群過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 關(guān)于Spring?@Transactional事務(wù)傳播機(jī)制詳解

    關(guān)于Spring?@Transactional事務(wù)傳播機(jī)制詳解

    我們?nèi)粘9ぷ髦袠O少使用事務(wù)傳播級(jí)別,單純只是使用事務(wù)和rollbackfor拋出異常來解決事務(wù)問題,但其實(shí)我們很多時(shí)候使用的是不正確的,或者說會(huì)造成事務(wù)粒度過大,本文詳解一下事務(wù)傳播級(jí)別,也讓自己更好地處理事務(wù)問題,需要的朋友可以參考下
    2023-08-08
  • 如何將SpringBoot項(xiàng)目打成?war?包并部署到Tomcat

    如何將SpringBoot項(xiàng)目打成?war?包并部署到Tomcat

    這篇文章主要介紹了如何將SpringBoot項(xiàng)目?打成?war?包?并?部署到?Tomcat,當(dāng)前環(huán)境是windows,tomcat版本是8.5采用的springboot版本是2.2.3,本文結(jié)合實(shí)例代碼給大家詳細(xì)講解需要的朋友可以參考下
    2022-11-11
  • Java注解@Transactional事務(wù)類內(nèi)調(diào)用不生效問題及解決辦法

    Java注解@Transactional事務(wù)類內(nèi)調(diào)用不生效問題及解決辦法

    這篇文章主要介紹了Java注解@Transactional事務(wù)類內(nèi)調(diào)用不生效問題及解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05

最新評(píng)論

安庆市| 广丰县| 恩施市| 梨树县| 平泉县| 屯门区| 石景山区| 怀仁县| 兴文县| 衡南县| 德安县| 福贡县| 东辽县| 西贡区| 监利县| 水富县| 大方县| 磴口县| 呈贡县| 武清区| 叶城县| 大洼县| 汝州市| 龙山县| 阳江市| 广南县| 原阳县| 博野县| 定结县| 赫章县| 洪洞县| 连山| 锡林郭勒盟| 正阳县| 西华县| 富锦市| 洛川县| 奉新县| 凤山市| 枣阳市| 武城县|