字符串匹配

原创 2016年06月01日 23:10:07

标签(空格分隔): 数据结构


1 串的定义

串(string):是零个或多个字符串组成的有限序列,又名叫字符串。

2. 朴素模式匹配算法

子串的定位操作通常称作串的模式匹配

using namespace std;
/**************************
函数功能:串的朴素匹配
参数说明:S:主串   T:子串
pos:开始查找子串的初始位置

说明:返回子串T在主串S中第pos个字符之后的位置。若不存在,则返回值为0
**************************/
int Index(string s, string t, int pos)
{
    int i = pos;//主串的起始索引位置
    int j = 0;//子串的起始索引位置
    while (i < s.length() && j < t.length())
    {
        if (s[i] == t[j])
        {
            ++i;
            ++j;
        }
        else
        {
            i = i - j + 2;//返回上次匹配的下一位置
            j = 0;
        }
    }
    if (j == t.length())
        return i - t.length();
    else
        return 0;

}

3. KMP模式匹配算法

D.E.Knuth、J.H.Morris和V.R.Pratt(其中,Knuth和Partt共同研究,Morris独立研究)发表一个模式匹配算法,可以大大避免重复遍历的情况,称之为克努特–莫里斯–普拉特算法,简称KMP算法

3.1 关于前缀及后缀

参照:http://kb.cnblogs.com/page/176818/
“前缀”指除了最后一个字符以外,一个字符串的全部头部组合;“后缀”指除了第一个字符以外,一个字符串的全部尾部组合。
“部分匹配值”就是”前缀”和”后缀”的最长的共有元素的长度。以”ABCDABD”为例,
  - “A”的前缀和后缀都为空集,共有元素的长度为0;
  - “AB”的前缀为[A],后缀为[B],共有元素的长度为0;
  - “ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
  - “ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
  - “ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;
  - “ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;
  - “ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。
  

3.2《算法导论》第32章中KMP算法的伪代码:

  1. 计算匹配的位置
KMP-MATCHER(T,P)//T:主串 P:子串(模式字符)
n=T.length
m=p.length
π=COMPUTE-PREFIX-FUNCTION(P)
q=0  //number of characters matched
for i=1 to n    //scan the text from left to right
   while q>0 and P[q+1]≠T[i]
         q=π[q]   //next characters does not match
   if P[q+1]==T[i]
      q=q+1  //next character matches
   if q==m  //is all of P matched ?
      print"Pattern occours with shift" i-m
   q=π[q]  //look for the next match
  1. 计算前缀函数
COMPUTE-PREFIX-FUNCTION(P)
m=P.length
let π[1...m] be a new array
π[1]=0
k=0
for q=2 to m
    while k>0 and P[k+1]≠P[q]
        k=π[k]
    if P[k+1]==P[q]
       k=k+1
    π[q]=k
return π

3.C语言KMP算法实现

/*计算前缀函数数组 pattern*/
int* ComputePreFix(const string &P)
{
    int m = P.length();
    int *pattern = new int[m];
    pattern[0] = 0;
    int k = 0;
    for (int q = 1; q < m; q++)
    {
        while (k>0 && P[k] != P[q])
            k = pattern[k - 1];
        if (P[k] == P[q])
            k += 1;
        pattern[q] = k;
    }
    return pattern;
}

/* KMP法进行字符串匹配*/
void KMP_matcher(const string &T, const string &P)
{
    int n = T.length();
    int m = P.length();
    int* pattern = ComputePreFix(P);
    int q = 0;//已匹配的字符串个数
    for (int i = 0; i < n; i++)
    {
        while (q>0&&P[q]!=T[i])
            q = pattern[q - 1];
        if (P[q] == T[i])
            q += 1;
        if (q == m)
        {
           cout << "Pattern occours with shift " << i - m+1;
           q = pattern[q - 1];
        }       
    }
    delete pattern;
    pattern = NULL;
}
int main()
{
    string T = "goodababacgooleababaca";
    string P = "ababaca";
    KMP_matcher(T, P);
}

USTCer 算法导论 字符串匹配实验

  • 2017年10月10日 11:52
  • 424KB
  • 下载

字符串匹配

  • 2015年03月07日 19:52
  • 336KB
  • 下载

字符串匹配算法(KMP、BM和Sunday),及Python实现

 分类: Python/Ruby 这篇博客主要对三种字符串匹配算法(KMP、BM、Sunday)进行总结。这三种字符串匹配算法之间的主要区别在于:如果在匹配过程中遇到一个不匹配位,该用...

字符串匹配之BM算法(英文)

  • 2013年10月16日 22:23
  • 1.14MB
  • 下载

字符串匹配

  • 2013年12月25日 16:18
  • 3KB
  • 下载

KMP字符串匹配算法的伪代码

KMP算法的图解:http://blog.csdn.net/u010232171/article/details/41945605 图解中的减法操作与下面的伪代码不同,应该以下面的代码为准 KMP...

字符串匹配的KMP算法浅析

  • 2014年08月26日 14:51
  • 139KB
  • 下载

字符串匹配

  • 2012年04月05日 12:52
  • 98KB
  • 下载

C++_字符串匹配_忽略大小写_方法

在我们平时的学习和工作中,我们经常需要对字符串进行各种比较,例如,忽略大小写比较,精确比较等。但目前 C++标准库并没有为string提供这样的方法,从而使我们不能方便的比较。所以碰到这种问题一般是自...

相似字符串匹配过滤算法研究.

  • 2016年04月15日 09:56
  • 12.05MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:字符串匹配
举报原因:
原因补充:

(最多只允许输入30个字)