字符串模式匹配算法系列(一):BF算法
算法背景:
BF(Brute Force)算法,是一种在字符串匹配的算法中,比较符合人类自然思维方式的方法,即对源字符串和目标字符串逐个字符地进行比较,直到在源字符串中找到完全与目标字符串匹配的子字符串,或者遍历到最后发现找不到能匹配的子字符串。算法思路很简单,但也很暴力。
算法原理:
假设源字符串为“非常地非常地非常地喜欢你”,我们想从中寻找目标字符串“非常地非常地喜欢”,则BF算法的过程可以表述如下:
第1轮:将源字符串和目标字符串对齐,并下标0开始逐个向后比较每个字符。结果发现双方的第1个字符都是“非”、第2个字符都是“常”、……,但到了第7个字符时发现不一致:源字符串为“非”、目标字符串为“喜”,因此这一轮匹配不成功。

第2轮:将目标字符串整体向后移动1个字符的位置(即将目标字符串的第1个字符与源字符串的第2个字符对齐),并开始逐个向后比较每个字符,结果发现两个字符串的第1个字符就不一致,因此这一轮匹配也不成功。

第3轮:类似地,将目标字符串整体向后移动1个字符的位置(即将目标字符串的第1个字符与源字符串的第3个字符对齐),并开始逐个向后比较,结果发现两个字符串的第1个字符就不一致,因此这一轮匹配也不成功。

第4轮:这一轮终于发现,目标字符串的每个字符都能和源字符串对应起来,匹配成功!因此算法结束并根据需要返回相应的信息(比如返回这一轮源字符串遍历起始点的位置下标3)

算法实现:
BF算法的python实现如下:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import pdb reload(sys)
sys.setdefaultencoding('utf-8') class BruteForce(object):
"""BF算法
成员变量:
str_s: 源字符串
str_t: 目标字符串
"""
def __init__(self, str_s, str_t):
self.str_s = str_s
self.str_t = str_t def run(self):
"""完全匹配则返回源字符串匹配成功的起始点的下标,否则返回-1
"""
base = 0 # 记录源字符串与目标字符串对齐的基准点
len_s = len(self.str_s)
len_t = len(self.str_t) while base + len_t <= len_s:
step = 0
while step < len_t:
if str_t[step] == self.str_s[base + step]:
# 当前字符相同,则继续比较下一个字符
step += 1
continue
# 当前字符不相同,则结束次轮比较,更新base基准位置,启动下一轮比较
base += 1
break
# 完全匹配成功,算法结论,返回匹配成功的基准点位置下标
if step == len_t:
return base
# 遍历了所有情况,最终匹配失败,返回-1
return -1 if __name__ == '__main__':
str_s = u"非常地非常地非常地喜欢你"
str_t = u"非常地非常地喜欢"
model = BruteForce(str_s, str_t)
print model.run()
复杂度分析:
时间复杂度:
假设源字符串长度为m,目标字符串长度为n,则:
最好情况下是第一轮就成功匹配,则时间复杂度为O(n);
最坏情况下是遍历到最后才成功匹配,或者遍历到最后发现匹配不成功,则时间复杂度为O(n*(m-n+1)),一般实际使用时m >> n,所以可以认为趋近于O(m*n);
空间复杂度:
由于不需要额外的存储空间,所以空间复杂度为O(1)
算法评估:
整个算法其实就循环执行如下两个步骤:
一、从每一轮的基准点开始比较两个字符串;
二、如发现不能完全匹配目标字符串,将目标字符串向后挪动一个字符的位置(即更新基准点);
如果想优化算法性能,那就简单分析一下:
步骤一基本没有优化的空间:两个字符串比较就是需要从前向后逐个字符看是否匹配;
步骤二可能有优化的空间:每轮发现不匹配时,目标字符串只能向后挪动一个字符的距离,所以会想到能否多往后挪动几个字符的距离?这样不就减少了步骤一比较的轮次数,从而加快速度了吗?这基本就是KMP算法的思路,下一篇《KMP算法》会详细介绍。
字符串模式匹配算法系列(一):BF算法的更多相关文章
- 字符串模式匹配算法系列(二):KMP算法
算法背景: KMP算法是由Donald Knuth和Vaughan Pratt于1970年共同提出的,而James H.Morris也几乎同时间独立提出了这个算法.因此人们将其称作“克努特-莫里斯-普 ...
- 字符串模式匹配算法系列(三):Trie树及AC改进算法
Trie树的python实现(leetcode 208) #!/usr/bin/env python #-*- coding: utf-8 -*- import sys import pdb relo ...
- Java数据结构之字符串模式匹配算法---Brute-Force算法
模式匹配 在字符串匹配问题中,我们期待察看源串 " S串 " 中是否含有目标串 " 串T " (也叫模式串).其中 串S被称为主串,串T被称为子串. 1.如果在 ...
- [转] 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 转载自:http://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boy ...
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 ...
- 字符串模式匹配算法--BF和KMP详解
1,问题描述 字符串模式匹配:串的模式匹配 ,是求第一个字符串(模式串:str2)在第二个字符串(主串:str1)中的起始位置. 注意区分: 子串:要求连续 (如:abc 是abcdef的子串) ...
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法
ref : https://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 KMP ...
- 字符串模式匹配算法1 - BF和KMP算法
在字符串S中定位/查找某个子字符串P的操作,通常称为字符串的模式匹配,其中P称为模式串.模式匹配有多种算法,这里先总结一下BF算法和KMP算法. 注意:本文在讨论字符位置/指针/下标时,全部使用C语法 ...
- Java数据结构之字符串模式匹配算法---KMP算法
本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...
随机推荐
- jvm性能监控(3)-jdk自带工具 jps jstack jmap
一.概要: jps -l 查看现有的java进程 jps -l 显示所有正在运行的java进程id jstack 查看Java线程 jstack -l pid; 做thread dump ...
- Linux系统配置Java开发基本环境
jdk安装一.用yum安装jdk1.查看yum库都有哪些jdk版本yum search java|grep jdk2.选择版本安装yum install java-1.8.0-openjdk(/usr ...
- java_第一年_JavaWeb(6)
会话 会话:浏览器从打开一个进程访问服务器到该浏览器关闭,我们称之为一个会话: 在浏览器和服务器交互期间,会不可避免地产生一些数据,而为了为每个用户保存其对应的数据,可使用两种技术:Cookie和Se ...
- Django学习记录--~Biubiubiu
Day One Django常用命令 1.创建Django网站框架 django-admin startproject mysite # mysite为定义的项目文件夹名称 2.超级用户创建 py m ...
- 一个神奇却很简单的css特效
在网上看到一个前端大牛的主页,觉得他有一个特效特别酷,一开始还以为是要用什么javascript代码来实现,但仔细看一下,发觉只是用几行css代码就搞定了,我觉得挺好的. 他这个效果就是鼠标放在左半部 ...
- redis 命令大全
全局命令: 1.查看所有键:keys * 2.键总数:dbsize 3.检查键是否存在:exists key 4.删除键:del key [key ...] 5.键过期:expire key seco ...
- navicat连接Oracle数据库提示错误 ORA-12514
这个是服务名写错了,服务名的字段在Oracle安装路径里找 这个我的服务名,这好像是重装Oracle就会变我之前的事orcl,重装之后发现连接不上数据库了,就倔强着找到了它 备注:如果是连接远程Ora ...
- 源码分析--ConcurrentHashMap与HashTable(JDK1.8)
ConcurrentHashMap和Hashtable都是线程安全的K-V型容器.本篇从源码入手,简要说明它们两者的实现原理和区别. 与HashMap类似,ConcurrentHashMap底层也是以 ...
- go语言从例子开始之Example31.定时器
我们常常需要在后面一个时刻运行 Go 代码,或者在某段时间间隔内重复运行. Go 的内置 定时器 和 打点器 特性让这些很容易实现.我们将先学习定时器,然后再学习打点器. Example: packa ...
- cookie和session的联系与区别
Cookie 当你在浏览网站时,WEB服务器会先送一小小的资料放在你的计算机上,Cookie会帮你在网站上所打的文字或是一些选择都记录下来.当你下次再光临同一个网站时,WEB服务器会先看看有没有它上次 ...