Java實現(xiàn)暴力匹配算法
一、什么是暴力匹配算法
暴力匹配算法,也稱為樸素匹配算法,是一種簡單的字符串匹配算法。它的基本思想是從文本串的第一個字符開始,逐個字符地與模式串進(jìn)行比較,如果匹配失敗,則將模式串向右移動一位,再與文本串的下一個字符進(jìn)行比較,直到找到匹配的子串或者文本串遍歷完畢。
具體實現(xiàn)時,我們可以使用兩個指針 i 和 j 分別指向文本串和模式串的首字符,然后逐個字符地進(jìn)行比較。如果當(dāng)前字符匹配成功,則兩個指針同時向后移動一位,繼續(xù)比較下一個字符;否則將模式串的指針 j 向右移動一位,重新從文本串的第 i 個字符開始匹配。
暴力匹配算法的時間復(fù)雜度為 O(mn),其中 m 和 n 分別為模式串和文本串的長度。在最壞情況下,需要將模式串移動 n-m+1 次,因此算法的效率較低,不適用于處理大規(guī)模的文本匹配問題。但是,暴力匹配算法的實現(xiàn)簡單、易于理解,是其他字符串匹配算法的基礎(chǔ),也是一些特殊情況下的最佳選擇。
二、代碼案例
package com.pany.camp.algorithm; /** ?* ?* @description: ?暴力匹配算法 ?* @copyright: @Copyright (c) 2022? ?* @company: Aiocloud ?* @author: pany ?* @version: 1.0.0? ?* @createTime: 2023-06-08 16:07 ?*/ public class BruteForcePatternMatching { ? ? public static int bruteForce(String text, String pattern) { ? ? ? ? int n = text.length(); ? ? ? ? int m = pattern.length(); ? ? ? ? for (int i = 0; i <= n - m; i++) { ? ? ? ? ? ? int j; ? ? ? ? ? ? for (j = 0; j < m; j++) { ? ? ? ? ? ? ? ? if (text.charAt(i + j) != pattern.charAt(j)) { ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? if (j == m) { ? ? ? ? ? ? ? ? return i; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return -1; ? ? } ? ? public static void main(String[] args) { ? ? ? ? String text = "hello world"; ? ? ? ? String pattern = "world"; ? ? ? ? int index = bruteForce(text, pattern); ? ? ? ? if (index == -1) { ? ? ? ? ? ? System.out.println("未找到匹配的子串"); ? ? ? ? } else { ? ? ? ? ? ? System.out.println("匹配成功,子串起始位置為:" + index); ? ? ? ? } ? ? } }
我們首先定義了一個名為 bruteForce 的靜態(tài)方法,用于實現(xiàn)暴力匹配算法。該方法接受兩個字符串參數(shù),分別為文本串和模式串,返回模式串在文本串中第一次出現(xiàn)的位置,如果未找到匹配的子串,則返回 -1。
然后,我們在 main 方法中定義了一個文本串和一個模式串,并調(diào)用 bruteForce 方法進(jìn)行匹配。如果匹配成功,則輸出匹配的子串起始位置;否則輸出未找到匹配的子串。
三、暴力匹配算法有什么缺點(diǎn)
暴力匹配算法的缺點(diǎn)是時間復(fù)雜度較高,最壞情況下需要比較 O ( n m ) O(nm)O(nm) 次,其中 n nn 是文本串的長度,m mm 是模式串的長度。當(dāng)文本串和模式串很長時,算法的效率會非常低下,甚至無法承受。
此外,暴力匹配算法只能找到第一個匹配的子串,并不能找到所有匹配的子串。如果需要找到所有匹配的子串,則需要使用其他算法,如 KMP 算法、Boyer-Moore 算法等。
因此,在實際應(yīng)用中,暴力匹配算法并不是一個很好的選擇,除非文本串和模式串的長度非常小且匹配次數(shù)較少。
四、暴力匹配算法和 String.indexOf 對比
暴力匹配算法和 indexOf 都可以用來在一個字符串中查找另一個字符串出現(xiàn)的位置,但是它們的實現(xiàn)方式有所不同。
暴力匹配算法是最簡單的字符串匹配算法,它的實現(xiàn)方式是從文本串的第一個字符開始,依次和模式串的每一個字符進(jìn)行比較,如果匹配成功,則繼續(xù)比較下一個字符,否則從文本串的下一個字符開始重新匹配。這個過程會一直持續(xù)到文本串的末尾或者匹配成功為止。暴力匹配算法的時間復(fù)雜度為 O(m*n),其中 m 和 n 分別為模式串和文本串的長度。
而 indexOf 是 Java 字符串類中提供的一個方法,可以用來查找一個字符串在另一個字符串中出現(xiàn)的位置。它的實現(xiàn)方式是從字符串的開頭開始,依次比較字符串中的每一個字符是否和目標(biāo)字符串的第一個字符相同,如果相同則繼續(xù)比較后面的字符,直到找到目標(biāo)字符串或者比較到字符串的末尾為止。如果找到了目標(biāo)字符串,則返回它在原字符串中的起始位置,否則返回 -1。indexOf 方法的時間復(fù)雜度為 O(n),其中 n 為原字符串的長度。
因為暴力匹配算法的時間復(fù)雜度較高,所以在大規(guī)模字符串匹配的場景中不適用,而 indexOf 方法則可以用來快速查找一個字符串在另一個字符串中的位置。
以下是暴力匹配算法和 indexOf 方法的性能對比數(shù)據(jù):
- 暴力匹配算法的時間復(fù)雜度為 O(m*n),其中 m 和 n 分別為模式串和文本串的長度。因此,當(dāng)字符串長度較大時,暴力匹配算法的性能會顯著下降。
- indexOf 方法的時間復(fù)雜度為 O(n),其中 n 為原字符串的長度。它采用了一些優(yōu)化技巧,如 Boyer-Moore 算法和快速查找表,能夠在大多數(shù)情況下快速定位目標(biāo)字符串的位置。
- 在實際測試中,暴力匹配算法的性能比 indexOf 方法差了很多。例如,在一個長度為 100000 的字符串中查找一個長度為 10 的子串,暴力匹配算法需要 3.5 秒左右,而 indexOf 方法僅需要 0.02 秒左右。
- 對于較短的字符串,兩種算法的性能差距并不明顯。例如,在一個長度為 100 的字符串中查找一個長度為 3 的子串,暴力匹配算法和 indexOf 方法的時間差別不到 0.001 秒。
綜上所述,當(dāng)需要在大規(guī)模字符串中查找子串時,推薦使用 indexOf方法,它能夠在大多數(shù)情況下快速定位目標(biāo)字符串的位置。而對于較短的字符串,兩種算法的性能差別并不明顯,可以根據(jù)具體情況選擇使用哪種算法。
到此這篇關(guān)于Java實現(xiàn)暴力匹配算法的文章就介紹到這了,更多相關(guān)Java 暴力匹配算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Spring?Batch實現(xiàn)大數(shù)據(jù)處理的操作方法
通過使用Spring?Batch,我們可以高效地處理大規(guī)模數(shù)據(jù),本文介紹了如何配置和實現(xiàn)一個基本的Spring?Batch作業(yè),包括讀取數(shù)據(jù)、處理數(shù)據(jù)和寫入數(shù)據(jù)的全過程,感興趣的朋友跟隨小編一起看看吧2024-07-07Java實現(xiàn)的求解經(jīng)典羅馬數(shù)字和阿拉伯?dāng)?shù)字相互轉(zhuǎn)換問題示例
這篇文章主要介紹了Java實現(xiàn)的求解經(jīng)典羅馬數(shù)字和阿拉伯?dāng)?shù)字相互轉(zhuǎn)換問題,涉及java輸入輸出及字符串、數(shù)組的遍歷與轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2018-04-04Maven依賴管理之parent與dependencyManagement深入分析
首先我們來說說parent標(biāo)簽,其實這個不難解釋,就是父的意思,pom也有繼承的。比方說我現(xiàn)在有A,B,C,A是B,C的父級?,F(xiàn)在就是有一個情況B,C其實有很多jar都是共同的,其實是可以放在父項目里面,這樣,讓B,C都繼承A就方便管理了2022-10-10詳細(xì)介紹idea如何設(shè)置類頭注釋和方法注釋(圖文)
本篇文章主要介紹了idea如何設(shè)置類頭注釋和方法注釋(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12Mybatis+Druid+MybatisPlus多數(shù)據(jù)源配置方法
在項目開發(fā)中,經(jīng)常需要連接多個數(shù)據(jù)庫,使用Mybatis、Druid和MybatisPlus可以實現(xiàn)多數(shù)據(jù)源配置,通過定義配置類和修改配置文件,如properties或yaml,可以設(shè)置多個數(shù)據(jù)源,本文介紹了配置項包括Druid基本配置、數(shù)據(jù)源一、數(shù)據(jù)源二,感興趣的朋友一起看看吧2024-09-09