求字符串可匹配的最大长度

如:text=“abcdlijkfgd”,query=“abcdefg”,最大匹配为“abcd”,为4。编写一个函数,求字符串可匹配的最大长度。

如果是完全匹配,则用很多种方法,如BF,KMP,sunday等字符串匹配算法。KMP是比较常见的,其思想也值得学习,先用其抛下砖。

字符串完全匹配:


我们需要先求出字符串query的next数组,就是字符串前缀等于后缀的最大长度,这里不祥述。

移动规则:

第一趟:从起始位开始,在字符‘c’处不相同,此时i=3、j=3、next[j]为1,若next[j]不为-1,则令j = next[j],则j=1。

第二趟:j=1,i=3。字符'a'与‘c'不匹配,next[j]=0,j=0,i不变

第三趟:字符’a'与‘c'不匹配,此时next[j]=-1,如next[j]为-1,那么i加1,j等于0。相当于i=4,此时query的起始位与i=4对齐。

然后一直如此进行下去,直至找到匹配的子串。

上程序:

//KMP算法

void KMP(char text[], int lenText, char array[], int lenArray)

{

    int *next = new int[lenArray];

    next = getNext(array, lenArray);

    int indexArray = 0;

    for (int pos=0; pos<lenText; ++lenText)

    {

        while (text[pos] == array[indexArray])

        {

            ++pos;

            ++indexArray;

        }

        if (next[indexArray] != -1)

        {

            indexArray = next[indexArray];

        }

        else

        {

            indexArray = 0;

        }

    }

    

}

int * getNext(char array[], int len)

{

    int *next = new int[len];

    next[0] = -1;

    next[1] = 0;

    for (int pos=2; pos<len; ++pos)

    {

        for (int k=1; k<pos; ++k)

        {

            int i=0;

            int j=k;

            int count = 0;

            while (array[i] == array[j] && j<pos)

            {

                ++count;

                ++i;

                ++j;

            }

            if (j == pos)

            {

                next[pos] = count;

                break;

            }

            else

            {

                next[pos] = 0;

            }

        }

    }

    return next;

}


但是题目并不是完全匹配,只是要求匹配的最大长度。


我们看到,开始最大匹配长度为3,如红色部分;在最后我们得到了一个最大的匹配为4,显然4才是我们所求。

我们可以设置一个max变量。先从字符串“ababd”进行匹配,得到一个最大的匹配长度,赋给max。然后从字符串“babd”进行匹配,得到一个最大匹配长度,赋给max。直到将“d”与text进行匹配。这样我们就可以得到最大的字符串匹配长度。


改进:如果这其中可以匹配到最后一个字符串,那么就可以截止了。如“ababd”进行匹配时,如果匹配到字符‘d’,那么肯定已经得到最大的了;如果没有匹配到最后一个字符,最大匹配长度为4,那么进行第二趟匹配;从字符串“babd”进行匹配,如果匹配到最后一个字符,那么我们便得到了最大匹配长度4,便可结束。


编程时,我们每趟匹配,字符串长度变了,相应的next数组也要变化。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值