c算法:字符串查找-KMP算法
/*
*用KMP算法实现字符串匹配搜索方法
*该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的
*字符串匹配,如果匹配,则输出文件名:包含该字符串的行
*待搜索的目标串搜索指针移动位数 = 已匹配的字符数 - 对应部分匹配值
*/ #include <stdio.h>
#include <string.h>
#include <stdlib.h> #define KEYWORD_MAX_LENGTH 100 //设定搜索串的最大长度 int kmp_table[KEYWORD_MAX_LENGTH]; //为搜索串建立kmp表
char prefix_stack[KEYWORD_MAX_LENGTH]; //前缀表达式栈
char suffix_stack[KEYWORD_MAX_LENGTH]; //后缀表达式栈
int keyword_length = ; //搜索串的长度
int record_position[KEYWORD_MAX_LENGTH]; //记录与关键字串匹配源串中的位置 /*
*GetMatchValue:获得字符串src的部分匹配值
"部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度。以"ABCDABD"为例, - "A"的前缀和后缀都为空集,共有元素的长度为0; - "AB"的前缀为[A],后缀为[B],共有元素的长度为0; - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0; - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0; - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1; - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2; - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0
*/
int GetMatchValue(char *src)
{
int value = ;
int src_len = strlen(src);
char *begin = src; //初始化指向字符串第一个字符
char *end = src + (src_len - ); //初始化指向字符串最后一个字符
int i = ;
for(i=;i<(src_len-);i++)
{
prefix_stack[i] = *begin;
suffix_stack[i] = *end; //待会prefix开头和suffix的结尾开始对比
begin++;
end--;
}
char *p = prefix_stack;
char *q = suffix_stack + (src_len - ); //指向栈中最后一个元素
int flag = ; //用一个标志位来确定后缀栈中到最后一个元素都与前缀栈中的符号匹配
while(q >= suffix_stack)
{
if(*p == *q)
{
value++;
p++;
flag=;
}
else {
flag = ;
}
q--;
}
if(flag == ) value = ;
return value;
} /*
*创建搜索字符串的KMP表
*/
int Create_KMP_Table(char *str,int *table)
{
int i;
char *dst;
keyword_length = strlen(str);
for(i=;i<keyword_length;i++)
{
if(i == ) {
table[i] = ; //第一个字符无前缀和后缀,所以为0
}
else {
dst = (char*)malloc((i+));
if(dst == NULL)
{
printf("malloc space error!\n");
return EXIT_FAILURE;
}
strncpy(dst,str,(i+)); //匹配str的前(i+1)个字符
dst[i+] = '\0'; //注意字符串要以'/0'结尾
table[i] = GetMatchValue(dst);
free((void*)dst);
}
}
return EXIT_SUCCESS;
} //打印搜索字符串对应的KMP表
void Table_Print(char *str,int *table)
{
int i;
char c = *str;
while(c != '\0')
{
printf("%-4c",c); //左对齐输出搜索字符串中的字符
c = *++str;
}
printf("\n");
for(i=;i<keyword_length;i++)
{
printf("%-4d",table[i]); //左对齐输出每个字符对应的部分匹配值
}
printf("\n");
} //在目标串dst_str中搜索关键子串search_str,打印出关键字串的位置信息,返回与关键字串匹配的数目
int Search_Keyword(char *dst_str,char *search_str)
{
char *p = dst_str;
char *q = search_str;
char *temp; //创建关键字串的KMP表
Create_KMP_Table(search_str,kmp_table); int count = ; //记录现在已经匹配的数目
int k = ; //记录与关键字串匹配的字串的数目
int move = ; //当字符串不匹配时,搜索指针移动的位数 while(*p != '\0') //直到搜索到目标串的最后一个字符为止
{
temp = p;
while(*q != '\0')
{
if(*q == *temp)
{
count++;
temp++;
q++;
}
else break;
} if(count == )
p++;
else {
if(count == keyword_length)
{
record_position[k++] = (temp-dst_str)-(keyword_length);
}
move = count - kmp_table[count-];
p += move;
} count = ;
q = search_str;
}
return k;
} int main(int argc,char **argv)
{
char *search_str = argv[];
char *dst_str = argv[];
int result=;
int i,j,num;
int before = ; if(argc != ){
printf("usage : ./kmp_test abc uipadcde\n");
} printf("Please input serach string and dst_string\n");
if(search_str == NULL)
{
printf("Please input search string\n");
return EXIT_FAILURE;
} if(dst_str == NULL)
{
printf("Please input dst_string\n");
return EXIT_FAILURE;
} //dst_str-目标字符串 search_str-需要查找的字符串
result = Search_Keyword(dst_str,search_str); //返回搜索到的结果的数目
Table_Print(search_str,kmp_table);
printf("%s\n",dst_str); //输出待搜索的目标串
if(result == )
{
printf("Sorry!Don't find the string %s\n",search_str);
return EXIT_SUCCESS;
}
else { for(i=;i<result;i++)
{
num = record_position[i] - before; //打印搜索串在目标串中的位置
before = record_position[i]+;
for(j=;j<=num;j++)
printf(" ");
printf("*");
}
printf("\n");
} return EXIT_SUCCESS;
}
c算法:字符串查找-KMP算法的更多相关文章
- 字符串查找KMP算法(转)
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- 字符串查找KMP算法
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
- 算法起步之kmp算法
[作者Idlear 博客:http://blog.csdn.net/idlear/article/details/19555905] 这估计是算法连载文章的最后几篇了,马上就要 ...
- 算法笔记之KMP算法
本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...
- 查找字符串的 KMP 算法
查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...
- KMP 算法 & 字符串查找算法
KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...
- KMP算法字符串查找子串
题目: 经典的KMP算法 分析: 和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多. 但是K ...
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
随机推荐
- Spring Boot入门第三天:配置日志系统和Druid数据库连接池。
原文链接 一.日志管理 1.在application.properties文件中加入如下内容: logging.level.root=WARN logging.level.org.springfram ...
- 数据结构(C语言版)-第2章 线性表
#define MAXSIZE 100 //最大长度 typedef struct { ElemType *elem; //指向数据元素的基地址 int length; //线性表的当前长度 }SqL ...
- maven---->配置,指令,插件,使用
maven是用于java的自动化构建工具. 1.下载:http://maven.apache.org/download.cgi 下载下面截图标红处的文件 然后直接解压可以得到文件夹,得到如下文件夹 不 ...
- 微信小程序如何导入字体图标
前提:我们已经拥有了从阿里图标库下载下来的一系列的字体图标文件1:找个其中的ttf格式的文件,然后打开https://transfonter.org/网站2:点击Add fonts按钮,加载ttf格式 ...
- CF1010F Tree
真·毒瘤题 这个题面写错了一句话.要求的是每个节点的石子树>=它的两个儿子石子数的和. 首先考虑怎么算石子分配的方案. 如果对这棵树每个节点的石子数都和儿子差分一下的话,可以唯一对应一颗每个点都 ...
- 优先队列优化dij算法
之前已经弄过模板了,但那个复杂一点,这个就是裸的dij,用起来更方便 输入格式:n,m,s,d分别是点数,边数,起点,终点 之后m行,输入x,y,z分别是两点即权值 题目链接:https://www. ...
- Leetcode 993. 二叉树的堂兄弟节点
993. 二叉树的堂兄弟节点 显示英文描述 我的提交返回竞赛 用户通过次数195 用户尝试次数229 通过次数195 提交次数462 题目难度Easy 在二叉树中,根节点位于深度 0 处,每个深 ...
- 八、持久层框架(MyBatis)
一.基于MyBatis的CRUD 1.首先是配置文件Category.xml修改 一次性修改配置文件Category.xml,提供CRUD对应的sql语句. <?xml version=&quo ...
- Binary Analysis Tool安装使用教程
Binary Analysis Tool(BAT)是一个用于检测二进制文件使用到的开源组件,协助及早发现程序发布后可能会面临的开源协议解执的开源免费检测工具. 一.安装BAT和bat-extratoo ...
- Windows平台dump文件的产生,调试;工程配置pdb文件怎么生成
http://blog.csdn.net/byxdaz/article/details/25872151