现在的位置: 首页 > 综合 > 正文

模式匹配

2013年02月03日 ⁄ 综合 ⁄ 共 1859字 ⁄ 字号 评论关闭
讲解正反模式匹配算法之前大家先回忆下以前学数据结构的时候学的串的模式匹配算法:
 
1.一般算法

初始条件:

ST存在,T是非空串,假如S为:a b  a b c
a b c a c b a b  T为:a b c a c

1posStrLength(S)

操作结果:若主串S中存在和串T值相同的子串,

则返回它在主串S中第pos个字符之后

第一次出现的位置;
否则函数值为0

...................................................

/ 返回子串T在主串S中第pos个字符之后的位置。

// 若不存在,则函数值为0

// 其中,T非空,1posStrLength(S)

int Index(SString S,SString T, int pos)   
{
    i=pos;
    j=1;
    while(i<=s[0] && j<=T[0])
    {
        if(s[i]==T[j])  / /继续比较后继字符
        {
            ++i;++j;
        }
        else             //指针后退重新开始匹配
        {
            i=i-j+2;
            j=1;
        }
    }
    if(j>T[0])
    {
        return i-T[o];
    }
    else  //若不存在则返回 0
    {
        return 0;
    }
}
以上算法就是自处理软件中哦好那个的“查找”/“替换”
.......上面算法的基本思想是:从主串S的第pos个字符起和模式的第一个字符比较,若想等,则继续逐个比较后续字符,否则从主串的下一个字符起再重新和模式的字符比较。依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功
最坏为O(m*n) 一般为O(m+n) 
 

2.首尾匹配算法

先比较模式串的第一个字符,再比较模式串的最后一个字符,最后比较模式串中从第二个到第n-1个字符。

 

int Index_FL(SString S,
SString T,
int pos)
{

    // 返回子串T在主串S中第pos个字符之后的位置。

    // 若不存在,则函数值为0。

    // 其中,T非空,1≤pos≤StrLength(S)。

    sLength
=
S[0];
tLength =
T[0];

    i =
pos;

    patStartChar
=
T[1];

    patEndChar
=
T[tLength];

    while (i
<=
sLength
tLength
+
1)
    {

        if (S[i]
!= patStartChar)
++i;
//重新查找匹配起始点

        else if (S[i+tLength-1]
!= patEndChar)
++i;

        // 模式串的“尾字符”不匹配

        else // 检查中间字符的匹配情况
        {

            k
=
1; j
=
2;

            while ( j
<
tLength
&&
S[i+k]
= T[j] )

            {
                 ++k;
++j;
            }

            if ( j
==
tLength )
           
                return i;

            else
                ++i;
// 重新开始下一次的匹配检测

        }

    }

    return 0;

}

上述两种算法的时间复杂度最坏为O(m*n)
 
 

Kmp算法(是一种改进算法,此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作):
其主要改进在于:每当一趟匹配过程中出现字符比较不等时,不需回溯i指针,而是利用已经得到的”部分匹配“的结果将模式向右滑动尽可能远的一段距离后,进行比较

 
int Index_KMP(SString S,
SString T,
int pos)
{

// 利用模式串T的next函数求T在主串S中第pos个

// 字符之后的位置的KMP算法。其中,T非空,

// 1≤pos≤StrLength(S)

i =
pos; j
= 1;

while (i
<=
S[0]
&& j
<= T[0])
{

if (j
==
0 || S[i]
== T[j])
{ ++i;
++j;
}

// 继续比较后继字符

else j
=
next[j];
// 模式串向右移动

}

if (j
>
T[0])
return i-T[0];
// 匹配成功

else return 0;

} // Index_KMP

 
 
 
 
 
 

抱歉!评论已关闭.