今天做了一道题,要用判断一个字符串是否是另一个字符串的子串,于是查了一下strstr的实现。

代码如下:

 char *strstr(const char*s1,const char*s2)
{
const char*p=s1;
const size_t len=strlen(s2);
for(;(p=strchr(p,*s2))!=;p++)
{
if(strncmp(p,s2,len)==)
return (char*)p;
}
return();
}

从上面的GCC中strstr实现代码可以分析出,strstr的时间复杂度是O(n2)的(因为strncmp是O(N)的),不过对长字符串匹配子串上可以采用kmp算法来提高效率(时间复杂度为O(m+n)),这里翻出了自己以前写的kmp算法的接口放到这里和大家分享一下,之前我也写过一篇关于kmp匹配子串的一篇文章,也可以去看一下。

这是我之前写的关于kmp介绍的文章地址:http://www.cnblogs.com/daimadebanyungong/p/4756853.html

下面是我翻出来的很早之前写的一个C版本的kmp算法的实现接口,欢迎纠正错误和分享经验。

 #include <string.h>
#include <stdio.h> #define LIB_MATCH_NUM 5
#define LIB_STRING_LEN 40 char lib_match[LIB_MATCH_NUM][LIB_STRING_LEN] =
{
"www.baidu.comw",
"www.google.com",
"www",
"baidu.com",
"lualu",
}; int lib_match_len[LIB_MATCH_NUM]; int lib_match_next[LIB_MATCH_NUM][LIB_STRING_LEN + ] = {}; void get_next(); void lib_match_init()
{
memset(lib_match_len,,sizeof(lib_match_len));
int i;
for(i = ; i < LIB_MATCH_NUM; i++)
{
lib_match_len[i] = strlen(lib_match[i]);
} get_next(); // init next array
} void get_next()
{
int i,j,k; for(i = ; i < LIB_MATCH_NUM; i++)
{ lib_match_next[i][] = ;
lib_match_next[i][] = ; k = ; //point to the last next[j]
int len = lib_match_len[i]; for( j = ; j < len; j++)
{//j start from 1 because next start from 2
k = lib_match_next[i][j]; //k = next[j]; while(k > && lib_match[i][j] != lib_match[i][k])
{
k = lib_match_next[i][k];
} if(lib_match[i][j] == lib_match[i][k])
{//s[j] == s[next[k]] next[i+1] = next[k] +1
k++;
} lib_match_next[i][j+] = k;
} } } int lib_search(char *orignal,int len)
{
if(orignal == NULL)
{
return ;
} int i,j,k; for(i = ; i < LIB_MATCH_NUM; i++)
{
char *tmp = orignal; // match each model need to start from the first
k = ; // k start from the last next array for(j = ; j < len; j++)
{ while( k > && tmp[j] != lib_match[i][k])
{
k = lib_match_next[i][k];
} if(tmp[j] == lib_match[i][k])
{
k++;
} if(k == lib_match_len[i])
{
printf("match the model string %d : %s\n", i,lib_match[i]);
printf("match at the position :%d\n\n", j - lib_match_len[i] + ); // here can return the i to know which model string have been matched k = lib_match_next[i][k]; //to match another this model string
} } } return ;
} void print_next()
{
int i,j; for(i = ; i < LIB_MATCH_NUM; i++)
{
printf("model string : %s \n",lib_match[i]);
printf("next array:");
for(j = ; j < lib_match_len[i]+;j++)
{
printf(" %d",lib_match_next[i][j]);
}
printf("\n\n");
}
} int main()
{
char orignal[]; lib_match_init(); print_next(); while()
{ scanf("%s",orignal); if(strcmp(orignal,"") == )
{
return ;
} lib_search(orignal,strlen(orignal));
} return ; }

Linux GCC下strstr的实现以及一个简单的Kmp算法的接口的更多相关文章

  1. Linux内核设计第三周——构造一个简单的Linux系统

    Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...

  2. 20135327郭皓--Linux内核分析第三周 构造一个简单的Linux系统MenuOS

    Linux内核分析第三周  构造一个简单的Linux系统MenuOS 前提回顾 1.计算机是如何工作的三个法宝 1.存储程序计算机 2.函数调用堆栈 3.中断 2.操作系统的两把宝剑 中断上下文的切换 ...

  3. linux内核分析 第三周 构造一个简单的Linux系统MenuOS

    一.计算机的三个法宝 存储程序计算机,函数调用堆栈,中断二.操作系统的两把剑:1.中断上下文的切换,保存现场和恢复现场2.进程上下文的切换. 三.linux内核源代码的分析: ·arch/目录保存支持 ...

  4. Linux内核分析第三周——构造一个简单的Linux系统MenuOS

    构造一个简单的Linux系统MenuOS 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...

  5. Linux第三周学习总结——构造一个简单的Linux系统MenuOS

    第三周学习总结--构造一个简单的Linux系统MenuOS 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  6. Windows 下针对python脚本做一个简单的进程保护

    前提: 大家运行的脚本程序经常会碰到系统异常关闭.或被其他用户错杀的情况.这样就需要一个进程保护的工具. 本文结合windows 的计划任务,实现一个简单的进程保护的功能. 利用py2exe生产 ex ...

  7. Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  8. 使用go, gin, gorm编写一个简单的curd的api接口

    go 是一门非常灵活的语言,既具有静态语言的高性能,又有动态语言的开发速度快的优点,语法也比较简单,下面是通过简单的代码实现了一个简单的增删改查 api 接口 hello world 常规版 新建 d ...

  9. linux下堆溢出unlink的一个简单例子及利用

    最近认真学习了下linux下堆的管理及堆溢出利用,做下笔记:作者作为初学者,如果有什么写的不对的地方而您又碰巧看到,欢迎指正. 本文用到的例子下载链接https://github.com/ctfs/w ...

随机推荐

  1. C++2.0新特性(三)——<=default,=delete、alias(别名)、noexcept、override、final、以及和const对比>

    一.=default,=delete 1.首先我们要回顾一下类默认函数的概念: C++中,当我们设计与编写一个类时,若不显著申明,则类会默认为我们提供如下几个函数: (1)构造函数(A()).(2)析 ...

  2. QThread 采用moveToThread方式实现多线程。 线程本身、connect关联的槽函数、connect关联的lambda对象分别运行在哪个线程中。

    Qt如何实现多线程:https://www.cnblogs.com/azbane/p/11372531.html September 5,2019 先抛出几个问题,用问题来引导思维导向: 1.继承的Q ...

  3. FPGA硬件加速

    FPGA市场占有率最高的两大公司Xilinx和Altera. 查找表(Look-Up-Table)简称为LUT,LUT本质上就是一个RAM.目前FPGA中多使用4输入的LUT,所以每一个LUT可以看成 ...

  4. prometheus安装(docker)

    参考:https://github.com/songjiayang/prometheus_practice https://github.com/kjanshair/docker-prometheus ...

  5. Java并发之多线程下竞态条件概念的理解

    一.简述 竞态条件(Race Condition):计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件. 二.常见竞态条件分析 最常见的竞态条件为 1.先检测后执行 执行依赖于检测的结果,而 ...

  6. maven 向私服部署jar

    1.有源码的情况下 首先需要在要deploy的项目pom中添加私服地址 <distributionManagement> <repository> <id>nexu ...

  7. PHP发送邮箱的方法smtp方法

    PHP发送邮箱的方法 采用的smtp方式首先进入163邮箱 设置  POP3/SMTP服务打勾 然后会提示你设置授权密码就是SMTP服务器的用户密码smtp.php文件代码<pre>< ...

  8. GIT 安装和使用

    目录 GIT 安装和使用 一.GIT 介绍 二.GIT 安装 三.GIT 使用 1. 配置 2. 创建版本库 3. 远程仓库 4. 分支管理 5.标签管理 6. 自定义 GIT 安装和使用 一.GIT ...

  9. Flink 源码解析 —— 项目结构一览

    Flink 源码项目结构一览 https://t.zsxq.com/MNfAYne 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac ...

  10. 『选课 树形dp 输出方案』

    这道题的树上分组背包的做法已经在『选课 有树形依赖的背包问题』中讲过了,本篇博客中主要讲解将多叉树转二叉树的做法,以便输出方案. 选课 Description 学校实行学分制.每门的必修课都有固定的学 ...