论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
快速字符串搜索算法KMP

[科技论文网] http://www.scipapers.com    2007-12-01  

    快速字符串搜索算法KMP

    在C/C++语言编程过程中,一般的字符串搜索操作都是通过标准库的strstr()函数来完成的,这在通常的情况下,因为字符串的搜索操作不多,并不会产生效率问题。实际上,这个函数的时间复杂度不容乐观。如果要从长度为n的字符串中查找长度为m的子字符串,那么这个strstr()函数的最坏时间复杂度为O(n*m),可见,随着子字符串长度m的增大,strstr()函数的时间复杂度也相应地成倍增加,有没有更加高效的算法呢?

    KMP(Knuth-Morris-Pratt)算法通过预先计算模式字符串中相应字符处的回溯索引,避免了模式匹配时不必要的回溯操作,从而提高了效率,将时间复杂度变成了O(m+n)。至于更加详细的内容,请教Google老师是个不错的主义,其中“KMP算法详解”这篇文章讲解的比较透彻,值得一看。

    KMP算法因为要保存每个字符的回溯索引,所以空间复杂度会略微有所增加

    sizeof(idx)*length(pattern)

    另外,当n比较小时,建立回溯索引所引入的O(m)个时间复杂度也许并不轻松。这些条件致使KMP算法适用于n和m都比较大,且字符串搜索操作比较频繁的环境,例如:网络入侵检测系统和QoS系统等。

    实际上Linux 2.6版内核从2.6.14开始就引入了名为string的iptables匹配(match)模块,他提供有KMP、BM(Boyer-Moore)和FSM(finite state machine)算法,可以实现基于关键字的网络过滤。

    在学习这个算法的过程中,将Linux内核中的实现代码搬到了用户空间:


    #include <assert.h>
    #include <stdio.h>

    void kmp_init(const char *patn, int len, int *next)
    {
            int i, j;

            assert(patn != NULL && len > 0 && next != NULL);
            next[0] = 0;
            for (i = 1, j = 0; i < len; i ++) {
                    while (j > 0 && patn[j] != patn[i])
                            j = next[j - 1];
                    if (patn[j] == patn[i])
                            j ++;
                    next[i] = j;
            }
    }

    int kmp_find(const char *text, int text_len, const char *patn,
                    int patn_len, int *next)
    {
            int i, j;

            assert(text != NULL && text_len > 0 && patn != NULL && patn_len > 0
                            && next != NULL);
            for (i = 0, j = 0; i < text_len; i ++ ) {
                    while (j > 0 && text[i] != patn[j])
                            j = next[j - 1];
                    if (text[i] == patn[j])
                            j ++;
                    if (j == patn_len)
                            return i + 1 - patn_len;
            }

            return -1;
    }

    int main(int argc, char *argv[])
    {
            int *next;
            int i, pos, len = strlen(argv[2]);

            if (argc < 3) {
                    printf("Usage: %s text pattern\n", argv[0]);
                    return 1;
            }

            next = calloc(strlen(argv[2]), sizeof(int));
            kmp_init(argv[2], strlen(argv[2]), next);
            printf("next array:\n");
            for (i = 0; i < len; i ++)
                    printf("\t%c", argv[2][i]);
            printf("\n");
            for (i = 0; i < len; i ++)
                    printf("\t%d", next[i]);
            printf("\n");

            pos = kmp_find(argv[1], strlen(argv[1]), argv[2], strlen(argv[2]), next);
            printf("find result:\n");
            if (pos < 0) {
                    printf("None found!\n");
            } else {
                    printf("%s\n", argv[1]);
                    for (i = 0; i < pos; i ++)
                            printf(" ");
                    printf("^\n");
            }

            return 0;
    }

        来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

  
快速字符串搜索算法KMP
下面没有链接了     最短路径算法源码
最新论文
·[程序设计]快速字符串搜索算法KMP
·[程序设计]最短路径算法源码
·[程序设计]模式串匹配问题总结
·[程序设计]稀疏矩阵相加的C程序
·[程序设计]逆置动态单链表
·[程序设计]采用比特位运算改进的N皇后算法
·[程序设计]快速排序C语言实现
·[程序设计]SHA1算法源代码
·[程序设计]利用二叉树结构的快速排序
·[程序设计]C语言有头结点链表的经典实现
 
 

搜索论文

Google
论文分类

论文网 论文发表网 论文 免费论文网 找论文网 毕业论文 中国论文网 英语论文 百度论文 聘教网 易搜
 免费发布论文    中国论文网 2008版权所有  业务联系:pinjiao@126.com