原理:KMP算法是一种模板匹配算法,它首先对模板进行便利,对于模板中与模板首字符一样和首字符进行标志-1,对于模板匹配中出现不匹配的若是第一轮检查标志为0,若不是第一轮检查标志为该元素与标志为-1的距离,在便利时通过检查有-1标签的数据标签进行往后检查,若不匹配,则直接跳到不匹配的位置(哨兵标记)进行往后检查。

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

typedef struct string string;
struct string
{
char *str;
int length;
};

double get_sys_time(void)
{
struct timeval time;
gettimeofday(&time,NULL);
return ((double)time.tv_sec + (double)time.tv_usec * 1.e-6);
}

string creat_string(int length)
{
string tmp_string;
tmp_string.str = (char *)malloc(sizeof(char) * (length + 1));
tmp_string.length = length;
return tmp_string;
}

string insert_string(char * str)
{
string tmp_string;
tmp_string.str = str;
tmp_string.length = strlen(str) + 1;
printf("sizeof str: %d\n",tmp_string.length);
return tmp_string;
}

int pure_find(string str,char * find_str)
{
int i = 0;
int j = 0;
while(*(str.str + i) != '\0')
{
if(*(find_str + j) == '\0') break;
if(*(str.str + i) == *(find_str + j))
{
j++;
}
else
j = 0;
i++;
}
if(i-j == str.length - 1) return -1;
return i - j;
}

int* find_Next(char *str)
{
int * Next;
Next = (int *)malloc(sizeof(int) * strlen(str));
int i = 0;
int j = 1;
int sentinel = 0;
Next[0] = -1;
int flags = 0;

while(str[j] != '\0')
{
if(str[0] == str[j] || str[j] == str[i])
{

if(str[0] == str[j])
{
Next[j] = -1;
sentinel = j;
flags = 1;
}
else
Next[j] = 0;
i++;

}
else
{
i = 0;
if(0 == flags)
Next[j] = 0;
else Next[j] = j - sentinel;
}
j++;
}

for(int circle = 0;circle < strlen(str);circle++)
{
printf("%3d",Next[circle]);
}
printf("\n");
return Next;
}

int KMP(int * Next,char * find_str,string str)
{
int sentinel = 0;//定义一个哨兵用于存放匹配错误时的消息
int j = 0;
int length = strlen(find_str);//获取到匹配字符串的长度
while(str.str[sentinel]!='\0')
{
if(j == -1 || str.str[sentinel] == find_str[j])
{
sentinel++;
j++;
}
else
{
j = Next[j];
}
if(j == length)
return sentinel - j;//到达模板长度
}
return -1;
}

int main(int argc,char *argv[])
{
string tmp_str;
//printf("argv:%s\n",argv[--argc]);
tmp_str = insert_string("XiaoXiaoXiaoEr");
double time = get_sys_time();
int num = pure_find(tmp_str,argv[argc - 1]);
printf("%s\n",argv[argc-1]);
time = get_sys_time() - time;
printf("pure cost time: %lf s\n",time);
if(num == -1)
{
printf("never find\n");
//return 0;
goto LOOP;
}
printf("出现在第 %d 位置\n",num);
LOOP: time = get_sys_time();
int *Next = find_Next(argv[argc - 1]);
num = KMP(Next,argv[argc - 1],tmp_str);
time = get_sys_time() - time;
if(num == -1)
{
printf("never find\n");
printf("KMP cost time: %lf s\n",time);
return 0;
}
printf("KMP cost time: %lf s\n",time);
printf("出现在第 %d 位置\n",num);

return 0;
}

KMP算法与传统字符串寻找算法的更多相关文章

  1. KMP算法 --- 在文本中寻找目标字符串

    KMP算法 --- 在文本中寻找目标字符串 很多时候,为了在大文本中寻找到自己需要的内容,往往需要搜索关键字.这其中就牵涉到字符串匹配的算法,通过接受文本和关键词参数来返回关键词在文本出现的位置.一般 ...

  2. 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)

    字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...

  3. 数据结构与算法--KMP算法查找子字符串

    数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...

  4. 算法之暴力破解和kmp算法 判断A字符串是否包含B字符串

    我们都知道java中有封装好的方法,用来比较A字符串是否包含B字符串 如下代码,contains,用法是 str1.contains(str2), 这个布尔型返回,存在返回true,不存在返回fals ...

  5. KMP 算法 & 字符串查找算法

    KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...

  6. KMP算法,匹配字符串模板(返回下标)

    //KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...

  7. Java字符串排列算法

    Java字符串排列算法 题目:现有ABCDE 5个球 构成的排列组合 可重复抽取 最多取到16个 共有多少种组合方式? 比如:取1个球可以构成的组合有 A B C D E 共5种,取2个球可以构成的组 ...

  8. Levenshtein字符串距离算法介绍

    Levenshtein字符串距离算法介绍 文/开发部 Dimmacro KMP完全匹配算法和 Levenshtein相似度匹配算法是模糊查找匹配字符串中最经典的算法,配合近期技术栏目关于算法的探讨,上 ...

  9. 前端与算法 leetcode 8. 字符串转换整数 (atoi)

    目录 # 前端与算法 leetcode 8. 字符串转换整数 (atoi) 题目描述 概要 提示 解析 解法一:正则 解法二:api 解法二:手搓一个api 算法 传入测试用例的运行结果 执行结果 G ...

随机推荐

  1. ffmpeg错误:Invalid UE golomb code

    解决方案在github https://github.com/FFmpeg/FFmpeg/commit/c51c08e0e70c186971385bdbb225f69edd4e3375 问题简要描述为 ...

  2. vue环境下新建项目

    1.之前电脑上安装了node和npm,查看下版本信息. 2.现在安装vue-cli脚手架,可以全局安装: npm install --global  vue-cli 之前自己电脑没有安装过webpac ...

  3. Java中值传递和引用传递的区别

    在Java中参数的传递主要有两种:值传递和参数传递: 下面是对两种传递方式在内存上的分析: 一:值传递 解释:实参传递给形参的是值  形参和实参在内存上是两个独立的变量 对形参做任何修改不会影响实参 ...

  4. 高可用Redis(三):Hash类型

    1.哈希类型键值结构 哈希类型也是key-value结构,key是字符串类型,其value分为两个部分:field和value 其中field部分代表属性,value代表属性对应的值 上面的图里,us ...

  5. 五 Zabbix全网监控

    监控的作用 我们的职责   1.保障企业数据的安全可靠.   2.为客户提供7*24小时服务.   3.不断提升用户的体验.在关键时刻,提前提醒我们服务器要出问题了当出问题之后,可以便于找到问题的根源 ...

  6. 利用MMdnn对比keras和mxnet

    关键字 MMdnn,keras,mxnet,resnet50 需求:想测试一下keras下model转到MXNet框架下对于同一张图片各中间层输出结果有什么差异. 一. 前期准备 1. 依赖库的选择 ...

  7. spark ML pipeline 学习

    一.pipeline 一个典型的机器学习过程从数据收集开始,要经历多个步骤,才能得到需要的输出.这非常类似于流水线式工作,即通常会包含源数据ETL(抽取.转化.加载),数据预处理,指标提取,模型训练与 ...

  8. 031 一次全面的java复习

    一:相关概念 1.面向对象的三个特征 封装,继承,多态,这个应该是人人皆知,有时候也会加上抽象. 2.多态的好处 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性.简单的说 ...

  9. Map接口下的集合和泛型理解

    一.Map接口 1. Map接口就是最顶层了,上面没有继承了.Map是一个容器接口,它与前面学的List.Set容器不同的是前面学的这些容器,一次只能传入一个元素,但是Map容器一次可以传入一对元素( ...

  10. Axure RP 8 软件介绍

    介绍 此软件可以用于制作快速原型,也可以绘制中保真原型草图. 应用人群:产品经理.交互设计师.UI设计师.网页设计师. 原型分类:低保真(手绘草图).中保真(使用相关软件绘制出来的).高保真(包含效果 ...