/*
*用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. 雷林鹏分享:XML 注意事项

    XML 注意事项 这里列出了您在使用 XML 时应该尽量避免使用的技术. Internet Explorer - XML 数据岛 它是什么?XML 数据岛是嵌入到 HTML 页面中的 XML 数据. ...

  2. piggy.lnk 简析

    piggy.lnk 简析 SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; * ...

  3. android -------- Data Binding的使用 ( 五) include

    Data Binding的中 include 标签的使用 inclune使用和原来一样,但要如何使数据也在 include中使用呢? 先看看我的布局文件 include的布局文件,也要使用 <l ...

  4. 反射API(一)

    <?php function classData(ReflectionClass $class) { echo '<hr>'; $details = '当前文件:'; $detail ...

  5. 1.1 从UNIX到Linux的发展历程

    MIT的CTSS:第一个分时操作系统 ◼ Multics系统(Multiplexed Information and Computing System) ⚫ 1965年AT&T,MIT和GE的 ...

  6. bzoj2875

    题意:\(x_{i+1}=(x_{i}*a+c)%m\)求,x_n%g 题解:\(x_n=(a^n*x_0+(a^{n-1}+a^{n-2}+...+a+1)*c)%m\),由于a-1和m不一定互质, ...

  7. Python PIL模块笔记

    利用python pil 实现给图片上添加文字 图片中添加文字#-*- coding: utf-8 -*- from PIL import Image,ImageDraw,ImageFont ttfo ...

  8. centos7-jdk快速安装

    安装之前先检查一下系统有没有自带open-jdk 命令: rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 如果没有输入信息表示没有安装. ...

  9. 【Java】【6】JDK8 Stream操作整理

    摘要: 1,List<EntityOld>转换为List<EntityNew> List<EntityOld> list = oldList; List<En ...

  10. navicat 连接 mysql 解决出现client does not support authentication protocol requested by server的问题

    MySQL8换了加密插件,数据库管理客户端都来不及更新,连接方式缺乏sha2的加密方式首先第一步, UPDATE mysql.user SET plugin = 'mysql_native_passw ...