将Linux内核中的KMP实现代码搬到了用户空间

转载 2007年10月14日 22:29:00
原贴:http://www.yuanma.org/data/2007/0420/article_2535.htm

在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算法!大家看看

#include "stdio.h"int next[100];void get_next(char T[],int next[]){ int i,j; i=1; j=0; next[1]=0; wh...
  • UncleQiong
  • UncleQiong
  • 2008-08-25 00:25:00
  • 882

KMP算法详解

只想Mark一下,原文地址:http://blog.csdn.net/yutianzuijin/article/details/11954939 kmp算法又称“看毛片”算法,是一个...
  • zhangyulin311
  • zhangyulin311
  • 2016-05-05 09:45:12
  • 465

KMP模式匹配算法(转自阮一峰)

通俗易懂的KMP模式匹配算法的原理
  • qq_31686787
  • qq_31686787
  • 2016-09-29 14:24:07
  • 409

将Linux内核中的KMP实现代码搬到了用户空间

原贴:http://www.yuanma.org/data/2007/0420/article_2535.htm在C/C++语言编程过程中,一般的字符串搜索操作都是通过标准库的strstr()函数来完...
  • chinalinuxzend
  • chinalinuxzend
  • 2007-10-14 22:29:00
  • 1176

KMP专题【完结】

第一题 hdu 1711 Number Sequence 点击打开hdu 1711 思路: 1 kmp是用来匹配字符串,只能够匹配单一的字符串 2 kmp的算法的过程:   1:假设文本串的长度为n...
  • cgl1079743846
  • cgl1079743846
  • 2013-11-21 13:18:20
  • 4128

Linux内核空间与用户空间的实现

实现用户内核空间和用户空间的分离是现代操作系统的必备能力。开始接触Linux时就就困惑于内核空间和用户空间的分离是如何实现的。查阅过一些材料,但很多都只是罗列了一些概念和一些简单的关系,并不能让我对这...
  • m0_37655049
  • m0_37655049
  • 2017-04-16 19:30:44
  • 771

Linux内核空间到用户空间的共享内存映射

当内核空间和用户空间存在大量数据交互时, 共享内存映射就成了这种情况下的不二选择; 它能够最大限度的降低内核空间和用户空间之间的数据拷贝, 从而大大提高系统的性能.   以下是创建从内核空间到用户...
  • brucexu1978
  • brucexu1978
  • 2013-02-27 12:54:38
  • 4659

KMP代码及思路解析

首先推荐这篇KMP思想的介绍:字符串匹配的KMP算法 KMP代码的关键是: 1、得到搜索串每个字符的匹配值 2、当字符匹配失败时的转移 (搜索串指搜索目标串。) 1: ...
  • windroid
  • windroid
  • 2015-04-12 21:00:25
  • 516

KMP算法详解

KMP算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配算法。但是相较于其他模式匹...
  • fengxinlinux
  • fengxinlinux
  • 2016-10-12 20:16:36
  • 1436

Linux内核源码分析—从用户空间复制数据到内核空间

Linux内核源码分析—从用户空间复制数据到内核空间 本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析从用户空间复制数据到内核空间函数。 1、不描述内核同步、错误处理...
  • weifenghai
  • weifenghai
  • 2016-10-16 21:52:54
  • 961
收藏助手
不良信息举报
您举报文章:将Linux内核中的KMP实现代码搬到了用户空间
举报原因:
原因补充:

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