/*
*用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算法的更多相关文章

  1. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  2. 字符串查找KMP算法

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  3. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  4. 算法起步之kmp算法

    [作者Idlear  博客:http://blog.csdn.net/idlear/article/details/19555905]            这估计是算法连载文章的最后几篇了,马上就要 ...

  5. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  6. 查找字符串的 KMP 算法

    查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...

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

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

  8. KMP算法字符串查找子串

    题目: 经典的KMP算法 分析: 和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多. 但是K ...

  9. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

随机推荐

  1. learn the python the hard way习题26~30总结

    考试试题26错误总结: 漏写字母,括号 写错字母 write(),read()的使用:只能打开使用了 open() 后返回的文件对象(file object),而不能直接使用文件名 if 语句中,条件 ...

  2. 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格惰性加载节点

    jQuery EasyUI 树形菜单 - 树形网格惰性加载节点 有时我们已经得到充分的分层树形网格(TreeGrid)的数据. 我们还想让树形网格(TreeGrid)按层次惰性加载节点. 首先,只加载 ...

  3. 批量显示QC结果的利器(转)

    作者:greenhillman MultiQC homepage: http://multiqc.info功能:把多个测序结果的qc结果整合成一个报告.支持fastqc.trimmomatic.bow ...

  4. Zabbix安装(debian,centos)

    lnmp和lamp架构搭建一键安装脚本下载地址:https://lnmp.org/download.html  https://github.com/teddysun/lamp/tree/master ...

  5. (Gorails) activeStore模块,把一堆属性放在一个hash对象内。gem 'activerecord-typedstore'增强了store模块,更好用了

    https://api.rubyonrails.org/classes/ActiveRecord/Store.html https://gorails.com/episodes/preferences ...

  6. lanmp环境一键安装

    yum install -y wgetwget http://dl.wdlinux.cn/files/lanmp_v3.2.tar.gztar zxvf lanmp_v3.2.tar.gzsh lan ...

  7. Spring boot @Autowired注解在非Controller中注入为null

    参考链接:https://blog.csdn.net/qq_35056292/article/details/78430777

  8. LVM(逻辑卷管理)从0到实战

    一.请看图 二.LVM——Logical Volume Manager LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小, ...

  9. java骰子求和算法

    //扔 n 个骰子,向上面的数字之和为 S.给定 Given n,请列出所有可能的 S 值及其相应的概率public class Solution { /** * @param n an intege ...

  10. Leetcode 1013. 总持续时间可被 60 整除的歌曲

    1013. 总持续时间可被 60 整除的歌曲  显示英文描述 我的提交返回竞赛   用户通过次数450 用户尝试次数595 通过次数456 提交次数1236 题目难度Easy 在歌曲列表中,第 i 首 ...