今天做了一道题,要用判断一个字符串是否是另一个字符串的子串,于是查了一下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. js 校验手机号码格式

      手机号码格式简单校验 原理:判断手机号是否以已经发行的手机号码段开头,而且判断其余9位是否是数字. 方式一: var phone = $('#phone').val(); var regex = ...

  2. [Gamma]Scrum Meeting#10

    github 本次会议项目由PM召开,时间为6月5日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译坐 ...

  3. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time

    Tomcat在启动是提示: INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least on ...

  4. 基于ZYNQ 的UART中断实验之串口写数据到DDR3中

    1.参考 UG585 网络笔记 2.理论知识 参见上一次实验:基于ZYNQ 的UART中断实验 3.实验目的 练习使用UART的中断实验,并将接收到的数据写入到DDR3中. 4.实验过程 建立工程,设 ...

  5. scala eval

    package com.jason case class JJ(d: Double*) object Ss { def main(args: Array[String]): Unit = { impo ...

  6. Effective.Java第56-66条(规范相关)

    56.  为所有已公开的API元素编写文档注释 要正确地记录API,必须在每个导出的类.接口.构造方法.方法和属性声明之前加上文档注释.如果一个类是可序列化的,还需要记录它的序列化形式. 文档注释在源 ...

  7. 百度前端技术学院task13源代码

    突然发现只看书不练习也是不行的,这么简单的我竟然都不会写了. 要注意innerHTML,innerText和outText之间的异同. 同时也要会使用DOM2的添加事件,移除事件等 <!DOCT ...

  8. jq 简单实现 table 显示和隐藏

    在做table显示和隐藏的时候,需要用到节点的问题.不要用id.循环的时候id都是一样的. 这样一个简单的tr显示和隐藏就实现了.也可以将click 换成别的事件.

  9. 使用PS打开图片的常见姿势

    我们经常会使用PS对现有的图片进行编辑.所以每个人都会经历打开图片这一步骤. 下面为大家介绍一下PS打开图片的这一步的常见方式吧: 第一种:使用文件资源管理器(也就是双击我的电脑弹出来的窗口) 第二种 ...

  10. #define宏作用

    预处理器的任务 简单来讲,预处理器的任务就是执行源代码中的预处理指令,并对源代码进行相应的处理.因此,从预处理指令的类型来讲,预处理器的任务包括如下的几个部分: 将其他文件包含到当前文件中. 定义宏, ...