字符串匹配(string matching)算法之一 (Naive and Rabin_Karp)

内容 来自《算法导论》《Introduction to algorithms》  作者CLRS

编辑by Touzani
http://blog.csdn.net/touzani/archive/2007/05/29/1628885.aspx


字符串匹配(String matching)

问题的形式定义: 假设文本(Text)是一个长度为n的数组T[1…n], 模式(Pattern)是一个长度为 mn.的数组P[1..m];. 又假设P和T中的元素都属于有限字母表 Σ 中的字符。 P 和T 常称为字符串。
如果0 ≤ s ≤ n – m 且T[s+1..s+m]=P[1…m], 则说P在T中出现且位移为s,此时成s为一个有效位移。
字符串匹配问题就变成在一个在一段制定的文本T中找出模式P的所有有效位移的问题。
 
下图给出了将要介绍的字符串匹配算法以及它们的预处理时间和匹配时间。
算法
预处理时间
匹配时间

朴素算法
0
O ((n - m + 1)m)
Rabin-Karp
Θ(m)
O ((n - m + 1)m)
有限自动机算法
O (m |Σ|)
Θ(n)
KMP 算法
Θ(m)
Θ(n)
 
记号:
用Σ* 表示用字母表 Σ中的所有有限长度的字符串的集合
字符串x的长度用| x |表示。
wy表示两个字符串w和y的连接。| wy | = | x |+| y |
 
 
字符串前缀  后缀

如果某个字符串 y ∈ Σ*,使得x=wy 。则称w是x的前缀, 记为w x 。 如果w是x的后缀,记为w x

 

可以把字符串匹配问题描述为 找出0 ≤ sn-m 并满足P Ts+m的所有位移s

 
1.)朴素的字符串匹配算法
NAIVE-STRING-MATCHER(T, P)
1 n ← length[T]
2 m ← length[P]
3 for s ← 0 to n - m
4     do if P[1 ‥ m] = T[s + 1 ‥ s + m]          // 隐含着一个循环
5           then print "Pattern occurs with shift" s

时间复杂度为 O(( n - m + 1) m), 如果 m = n/2 . 那么时间复杂度为 Θ( n 2), 这个算法效率不高,原因在于对于s的一个值,获得的关于文本的信息在考虑s的其他值时完全被忽略了。
例如,如果 P=aaab,设s=0 是有效的,那么 s=1, 2, 3 就不可能是有效位移,因为T[4]=b.
 
 
2.) Rabin-Karp字符串匹配算法,
 
实际应用中,Rabin和Karp建议的字符串匹配算法能较好地运行,还可以归纳出有关问题地其他算法,如二维模式匹配。
 
假定字符集Σ ={0, 1, 2, ……, 9}, 每一个字符对应一个十进制数字
(一般情况, 假定每个字符是基数为d的表示法中的一个数字, d=|Σ|。)可以用一个长度为k的十进制数字来表示由k个连续字符组成的字符串.

因此,字符串"31415" 对应于十进制数31415

已知模式P[1..m],设p表示其相应十进制数地值,类似地, 对于给定的文本T[1..n]. 用

ts 表示长度为m的子字符串 T[ s + 1 ‥ s + m]( s = 0, 1, . . . , nm),  ts = p 当且仅当 [ s + 1 ‥ s + m] = P[1 ‥ m]; 因此s是有效位移当且仅当 ts = p. (暂不考虑p和 ts 可能是很大的数的情况)。

可以用霍纳规则(Horner’s rule) 在Θ(m) 的时间内计算p的值

p = P[m] + 10 (P[m - 1] + 10(P[m - 2] + · · · + 10(P[2] + 10P[1]) )).

 
Horner’s rule

https://p-blog.csdn.net/images/p_blog_csdn_net/touzani/303255/o_image002.jpg

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: BF算法,也称为暴力匹配算法,是一种简单的字符串匹配算法。它的基本思想是从主串的第一个字符开始,依次与模式串的每一个字符进行比较,如果匹配成功,则继续比较下一个字符,否则主串向右移动一位,重新开始匹配。 具体实现步骤如下: 1. 定义主串和模式串两个字符串。 2. 从主串的第一个字符开始,依次与模式串的每一个字符进行比较。 3. 如果匹配成功,则继续比较下一个字符,直到模式串的最后一个字符都匹配成功。 4. 如果匹配失败,则主串向右移动一位,重新开始匹配。 5. 如果主串的长度小于模式串的长度,则匹配失败。 6. 如果主串的长度等于模式串的长度,且每个字符都匹配成功,则匹配成功。 下面是一个简单的BF算法实现代码: ``` #include <iostream> #include <string> using namespace std; int BF(string s, string p) { int i = 0, j = 0; while (i < s.length() && j < p.length()) { if (s[i] == p[j]) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j == p.length()) { return i - j; } else { return -1; } } int main() { string s = "hello world"; string p = "world"; int pos = BF(s, p); if (pos == -1) { cout << "not found" << endl; } else { cout << "found at position " << pos << endl; } return 0; } ``` 在上面的代码中,BF函数接受两个字符串参数s和p,分别表示主串和模式串。函数返回值为匹配成功的位置,如果匹配失败则返回-1。在函数中,使用两个指针i和j分别指向主串和模式串的第一个字符,依次进行比较。如果匹配成功,则i和j都向后移动一位;如果匹配失败,则i回退到上一次匹配的下一个位置,j回退到模式串的第一个字符。最后,如果j等于模式串的长度,则表示匹配成功,返回i-j的值即可。 ### 回答2: bf算法(Brute-Force 算法)是一种简单的字符串模式匹配算法。它的思想是通过对两个字符串逐个字符进行比较来判断字符串是否匹配。以下是用Python编写的一个简单的bf算法实现: ```python def pattern_matching(text, pattern): n = len(text) m = len(pattern) for i in range(n-m+1): j = 0 while(j < m): if (text[i+j] != pattern[j]): break j += 1 if (j == m): return i return -1 text = 'ABCABCDABABCDABCDABDE' pattern = 'ABCDABD' index = pattern_matching(text, pattern) if (index == -1): print("无匹配结果") else: print("匹配结果在字符串中的索引位置为:", index) ``` 在上述代码中,pattern_matching函数接受两个参数text和pattern,其中text是待匹配字符串,pattern是需要匹配字符串。程序通过逐个字符比较来判断字符串是否匹配。如果找到了匹配的子串,则返回匹配的子串在text中的索引位置。如果没有找到匹配的子串,则返回-1。 例如,在上述示例中,待匹配字符串是'ABCABCDABABCDABCDABDE',需要匹配字符串是'ABCDABD'。由于该模式在主字符串中存在,所以匹配结果在字符串中的索引位置为6。 通过bf算法,我们可以快速实现一个简单的字符串模式匹配算法。然而,bf算法的时间复杂度较高,在最坏情况下为O(n * m),其中n为主字符串的长度,m为模式字符串的长度,因此在处理大规模的字符串匹配时,可能不适用。 ### 回答3: BF(Brute Force)算法,也称为朴素模式匹配算法,是一种简单的模式匹配算法。它的基本思想是,从文本串的起始位置开始逐个字符与模式串进行比较,当发现不匹配时,将文本串向右移动一位,再重新开始比较。当匹配成功时,返回模式串在文本串中的起始位置,否则返回-1。 以下是使用Python编写的BF算法的实现: ```python def BF(pattern, text): pattern_len = len(pattern) text_len = len(text) for i in range(text_len - pattern_len + 1): found = True for j in range(pattern_len): if pattern[j] != text[i+j]: found = False break if found: return i return -1 ``` 使用该算法进行模式匹配的示例: ```python text = "Hello, world!" pattern = "world" index = BF(pattern, text) if index == -1: print("未找到匹配的模式") else: print("模式在文本中的起始位置为:", index) ``` 运行结果为: ``` 模式在文本中的起始位置为: 7 ``` 在上述代码中,`BF`函数接受两个参数,分别是待匹配的模式串`pattern`和文本串`text`。首先计算模式串和文本串的长度,并使用两个循环来逐个比较字符。如果发现不匹配,则将文本串向右移动一位,再重新开始比较。如果匹配成功,则返回模式串在文本串中的起始位置,否则返回-1。 以上就是简单模式匹配算法(BF算法)的Python实现。由于BF算法的时间复杂度较高,通常在处理大规模的模式匹配问题时会选择更高效的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值