字符串模式匹配算法系列(一):BF算法


算法背景:

BF(Brute Force)算法,是一種在字符串匹配的算法中,比較符合人類自然思維方式的方法,即對源字符串和目標字符串逐個字符地進行比較,直到在源字符串中找到完全與目標字符串匹配的子字符串,或者遍歷到最后發現找不到能匹配的子字符串。算法思路很簡單,但也很暴力。

算法原理:

假設源字符串為“非常地非常地非常地喜歡你”,我們想從中尋找目標字符串“非常地非常地喜歡”,則BF算法的過程可以表述如下:

第1輪:將源字符串和目標字符串對齊,並下標0開始逐個向后比較每個字符。結果發現雙方的第1個字符都是“非”、第2個字符都是“常”、……,但到了第7個字符時發現不一致:源字符串為“非”、目標字符串為“喜”,因此這一輪匹配不成功。

第2輪:將目標字符串整體向后移動1個字符的位置(即將目標字符串的第1個字符與源字符串的第2個字符對齊),並開始逐個向后比較每個字符,結果發現兩個字符串的第1個字符就不一致,因此這一輪匹配也不成功。

第3輪:類似地,將目標字符串整體向后移動1個字符的位置(即將目標字符串的第1個字符與源字符串的第3個字符對齊),並開始逐個向后比較,結果發現兩個字符串的第1個字符就不一致,因此這一輪匹配也不成功。

 第4輪:這一輪終於發現,目標字符串的每個字符都能和源字符串對應起來,匹配成功!因此算法結束並根據需要返回相應的信息(比如返回這一輪源字符串遍歷起始點的位置下標3)

 

算法實現:

BF算法的python實現如下: 

 1 #!/usr/bin/env python
 2 #-*- coding: utf-8 -*-
 3 import sys
 4 import pdb
 5 
 6 reload(sys)
 7 sys.setdefaultencoding('utf-8')
 8 
 9 
10 class BruteForce(object):
11     """BF算法
12     成員變量:
13         str_s: 源字符串
14         str_t: 目標字符串
15     """
16     def __init__(self, str_s, str_t):
17         self.str_s = str_s
18         self.str_t = str_t
19 
20     def run(self):
21         """完全匹配則返回源字符串匹配成功的起始點的下標,否則返回-1
22         """
23         base = 0 # 記錄源字符串與目標字符串對齊的基准點
24         len_s = len(self.str_s)
25         len_t = len(self.str_t)
26 
27         while base + len_t <= len_s:
28             step = 0
29             while step < len_t:
30                 if str_t[step] == self.str_s[base + step]:
31                     # 當前字符相同,則繼續比較下一個字符
32                     step += 1
33                     continue
34                 # 當前字符不相同,則結束次輪比較,更新base基准位置,啟動下一輪比較
35                 base += 1
36                 break
37             # 完全匹配成功,算法結論,返回匹配成功的基准點位置下標
38             if step == len_t:
39                 return base
40         # 遍歷了所有情況,最終匹配失敗,返回-1
41         return -1
42 
43 
44 if __name__ == '__main__':
45     str_s = u"非常地非常地非常地喜歡你"
46     str_t = u"非常地非常地喜歡"
47     model = BruteForce(str_s, str_t)
48     print model.run()

 

復雜度分析: 

時間復雜度:

假設源字符串長度為m,目標字符串長度為n,則:

最好情況下是第一輪就成功匹配,則時間復雜度為O(n);

最壞情況下是遍歷到最后才成功匹配,或者遍歷到最后發現匹配不成功,則時間復雜度為O(n*(m-n+1)),一般實際使用時m >> n,所以可以認為趨近於O(m*n);

空間復雜度:

由於不需要額外的存儲空間,所以空間復雜度為O(1)

算法評估:

整個算法其實就循環執行如下兩個步驟:

一、從每一輪的基准點開始比較兩個字符串;

二、如發現不能完全匹配目標字符串,將目標字符串向后挪動一個字符的位置(即更新基准點);

如果想優化算法性能,那就簡單分析一下:

步驟一基本沒有優化的空間:兩個字符串比較就是需要從前向后逐個字符看是否匹配;

步驟二可能有優化的空間:每輪發現不匹配時,目標字符串只能向后挪動一個字符的距離,所以會想到能否多往后挪動幾個字符的距離?這樣不就減少了步驟一比較的輪次數,從而加快速度了嗎?這基本就是KMP算法的思路,下一篇《KMP算法》會詳細介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM