KMP算法与传统字符串寻找算法
原理: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算法与传统字符串寻找算法的更多相关文章
- KMP算法 --- 在文本中寻找目标字符串
KMP算法 --- 在文本中寻找目标字符串 很多时候,为了在大文本中寻找到自己需要的内容,往往需要搜索关键字.这其中就牵涉到字符串匹配的算法,通过接受文本和关键词参数来返回关键词在文本出现的位置.一般 ...
- 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...
- 数据结构与算法--KMP算法查找子字符串
数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...
- 算法之暴力破解和kmp算法 判断A字符串是否包含B字符串
我们都知道java中有封装好的方法,用来比较A字符串是否包含B字符串 如下代码,contains,用法是 str1.contains(str2), 这个布尔型返回,存在返回true,不存在返回fals ...
- KMP 算法 & 字符串查找算法
KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...
- KMP算法,匹配字符串模板(返回下标)
//KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...
- Java字符串排列算法
Java字符串排列算法 题目:现有ABCDE 5个球 构成的排列组合 可重复抽取 最多取到16个 共有多少种组合方式? 比如:取1个球可以构成的组合有 A B C D E 共5种,取2个球可以构成的组 ...
- Levenshtein字符串距离算法介绍
Levenshtein字符串距离算法介绍 文/开发部 Dimmacro KMP完全匹配算法和 Levenshtein相似度匹配算法是模糊查找匹配字符串中最经典的算法,配合近期技术栏目关于算法的探讨,上 ...
- 前端与算法 leetcode 8. 字符串转换整数 (atoi)
目录 # 前端与算法 leetcode 8. 字符串转换整数 (atoi) 题目描述 概要 提示 解析 解法一:正则 解法二:api 解法二:手搓一个api 算法 传入测试用例的运行结果 执行结果 G ...
随机推荐
- ffmpeg错误:Invalid UE golomb code
解决方案在github https://github.com/FFmpeg/FFmpeg/commit/c51c08e0e70c186971385bdbb225f69edd4e3375 问题简要描述为 ...
- deepin(debian)下使用Git
Github github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开. 安装git 安装 sudo apt-get install g ...
- WOW.js – 让页面滚动更有趣
官网:http://mynameismatthieu.com/WOW/ 建议去官网一看 下载地址:https://github.com/matthieua/WOW 浏览器兼容 IE10+ Chrom ...
- PHP 递归几种方法
一.利用静态变量的方法 <?php function call(){ static $i = 0; echo $i . ''; $i++; if($i<10){ call(); } } c ...
- 公设基础equals
1# 覆盖equals方法的通用约定 1.自反性(reflexive) 自己跟自己的比较必须返回true 2.对称性(symmetric) x=y那么y=z 3.传递性(transitive) x= ...
- html网页引用中文字体,解决加载缓慢办法
[ttf 压缩]html网页引用中文字体,文件过大,加载缓慢的解决办法[字蛛][web font] [字蛛]http://font-spider.org/ 先安装好 NodeJS,然后执行: npm ...
- TPshop之邮箱注册配置教程--附加常见问题集合
准备:企业邮箱(开启POP/SMTP功能) 一.步骤教程: 1.登录企业邮箱(QQ邮箱示例) QQ邮箱 POP3:pop.qq.com SMTP:smtp.qq.com SMTP端口号:25 邮箱 ...
- 烽火2640路由器命令行手册-12-IBM网络配置命令
IBM网络配置命令 目 录 第1章 DLSW配置命令... 1 1.1 DLSW配置命令... 1 1.1.1 dlsw local-peer 1 1.1.2 dlsw remote-peer 3 ...
- [原创]EBAZ4205 Linux log打印输出
下载器与板级之前的连接 JTAG红色为1脚,请注意 RX接板级TX TX接板级RX UART_Vref接板级VCC GND接板级GND U-Boot 2014.01 (Apr 14 2019 - 10 ...
- css居中,margin_and_position
首先父元素肯定是要相对定位的,其次我们上下左右居中的元素的css如下: width: 50px; height: 50px; margin: auto; position: absolute; lef ...