zoukankan      html  css  js  c++  java
  • 高速字符串匹配 zzl算法

    这个大概我这段时间稍微有点成就感的东西了。 学了数据结构,但是编写代码的时候还是照着书抄,没有一点意思…… 字符串匹配在补丁的时候是非常有用的。 之前我用的普通方法查找,就是一个一个的往前。搜索一个300kb的文件大概需要4秒时间。 看了ZZL算法原理以后,自己就编写了出来。查找这个相同的文件,需时约0.4秒。 大家能够感觉到差距吧?整整10倍啊! 算法思想大意是每次能够尽量多的移动匹配位置,因此建立一个开始匹配的索引。 整个程序需要两部 预处理 预处理主要完成查找模式串首字符在主串中的所有出现位置,并将其保存在一个数组中。 查找模式串首字符算法如下: k=0; for(i=start;i<S.length-T.length;i++) { if(S.str[i]==T.str[0]) { x[k]=i; k++; // k为模式串首字母在主串中出现的次数 } } 匹配 在预处理的基础上,字符串匹配算法就可以从查找到的模式串在主串中的位置开始,匹配模式串首字母之后的其余部分。此时,采用BF算法即可,并可设置一个计数器,记录匹配次数。 匹配算法如下: v=0; for(m=0;m<k;m++) { for(j=1;j<T.length;j++) { if(S.str[x[m]+1]==T.str[j]) { v++; x[m]++; } else { v++; break; } } } 算法性能分析 如果不考虑算法的预处理过程,若模式串首字母在主串中出现k次,则ZZL算法最坏情况下比较次数为k*(M-1) 如果考虑算法的预处理过程,则总的比较次数需再加上N次,即为k*M+N。 最后,我把我实现的算法写出来吧,可不是伪代码哦,保证能够编译通过的。 //www.shuax.com //舒俊杰 2009.11.29 #include <stdio.h> #include <stdlib.h> int main() { int key[] = {0x74, 0x07, 0xB8, 0x04, 0x40, 0x00, 0x80, 0xEB, 0x0F}; FILE *fp; fp = fopen("XLUser.dll", "rb"); fseek(fp, 0L, 2); long filelen = ftell(fp);//为了加快速度,可自定义文件长度 long feature = 0; long point; //索引顺序表 int length = 200; long *seek = (long *)malloc(length * sizeof(long)); int i = 0; int j = 0; //建立索引,我自己改进了一下ZZL //既然可以查询首字符,那么一次查询两个也行吧? fseek(fp, 0L, 0); while (ftell(fp) < filelen ) { if (fgetc(fp) == key[0] && fgetc(fp) == key[1]) { feature++; if (feature == length) { seek = (long *)realloc(seek, (length + 40) * sizeof(long)); length += 40; } seek[feature] = ftell(fp); } } //根据索引查找 for (i = 0;i < feature;i++) { fseek(fp, seek[i], 0); for (j = 2; j < 9;j++) { if (fgetc(fp) != key[j]) break; } if (j > 8) point = ftell(fp); } fclose(fp); printf("%x", point); return 0; } 这个就是我的迅雷补丁的核心算法啦…自我感觉良好…哈哈 实验结果 为 了评测该算法的性能,随机的抽取一段文本和模式串,并在同一台计算机上用不同的算法进行匹配。测试文本主串S=”Fromautomated teller machines and atomic clocks to mammograms andsemiconductors,innumerable products and services rely in some way ontechnology,measurement,and standards provided by the National Instituteof Standards and Technology”,模式串T=”products andservices”。分别用BF算法、KMP算法、BM算法、Sunday算法和ZZL算法在同一台计算机上进行匹配计算,并统计每种算法匹配时总 的字符匹配次数。测试结果: 算法 BF KMP BM Sunday ZZL 一次匹配的总的字 符匹配次数 116 95 108 110 23 转:http://www.shuax.com/?p=871
  • 相关阅读:
    队列
    栈的链式存储
    单例和多例设计模式
    顺序栈的基本操作
    串的模式匹配
    线性表的链式存储结构
    倒置顺序表
    回文序列
    go语言系列-从运算符到函数
    go语言系列-从零到数据类型
  • 原文地址:https://www.cnblogs.com/adodo1/p/4327927.html
Copyright © 2011-2022 走看看