PHP源代码分析-字符串搜索系列函数实现详解
今天和同事在讨论关键字过虑的算法实现,前几天刚看过布隆过滤算法,于是就想起我们公司内部的查找关键字程序,好奇是怎么实现的。于是查找了一下源代码,原来可以简单地用stripos函数查找,
stripos原型如下:
int stripos ( string $haystack, string $needle [, int $offset] )
一般地都会建一个关键词库,然后把 用户输入的内容作为haystack,然后循环遍历一下关键词库,把每个关键词作为needle,如果存在的话则会返回关键字在输入的内容中的位置。
于是查找了一下PHP源代码关于这个函数的实现,如果想知道一个函数在PHP的哪个模块的话可以简单写一个函数get_module. php
<?php
if(substr(php_sapi_name(),0,6)=='cli'){ global $argv; $function = $_GET['name']; ?> |
字符串系列的函数属于PHP的标准模块,在ext/standard目录下,string.c 文件。
PHP_FUNCTION(stripos) { char *found = NULL; char *haystack; int haystack_len; long offset = 0; char *needle_dup = NULL, *haystack_dup; char needle_char[2]; zval *needle; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) { if (offset < 0 || offset > haystack_len) { if (haystack_len == 0) { haystack_dup = estrndup(haystack, haystack_len); php_strtolower(haystack_dup, haystack_len); if (Z_TYPE_P(needle) == IS_STRING) { if (Z_STRLEN_P(needle) == 0 || Z_STRLEN_P(needle) > haystack_len) { needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle)); found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len); switch (Z_TYPE_P(needle)) { } efree(haystack_dup); if (found) { RETURN_LONG(found - haystack_dup); |
查找函数是由php_memstr实现的,在main目录下的php.h文件
#define php_memnstr zend_memnstr
所以真正的函数是zend_memnstr,在zend/目录下面的zend_operators.h,
static inline char * zend_memnstr(char *haystack, char *needle, int needle_len, char *end) { char *p = haystack; char ne = needle[needle_len-1]; end -= needle_len; while (p <= end) { if (p == NULL) { p++; return NULL; |
查到这里就能看到实现搜索的原理了,主要用了一个while循环和两个C的函数memchr和memcmp。
先用第一个函数查找needle的第一个字符在haystack中出现的位置,然后调用memcmp,从这个位置开始比较needle和haystack,如果相同就返回这个位置,没有的话再把指针指向haystack的下一位再进行比较,一直到最后。
不过这个搜索只是简单地调用了memchr和memcmp函数,至于memcmp用了什么算法比较两个字符串就不太清楚,我们知道在一个长度为n的字符串里面查找字符串为m的字符串,那么最坏的 时间复杂度是O(n*m),上网搜了一下memcmp,不过没有找到他的实现原理。后来想了一下发现这个其实就是最简单的两次循环遍历进行比较。看了一下PHP的其他几个字符串查找函数strstr,stristr,strpos,strrpos,strripos 等函数都是调用zend_memnstr这个函数实现的,只是在返回的时候内容不同而已。
PHP源代码分析-字符串搜索系列函数实现详解相关推荐
- C语言中itoa系列函数及sprintf系列函数使用详解
C语言中itoa系列函数及sprintf系列函数使用详解 itoa函数系列 该系列函数是广泛使用的非标准C语言和C++语言扩展功能,只能在windows编译器下使用,如果涉及到跨平台是不允许使用的,这 ...
- C语言中的字符串转数字函数常见问题详解
目录 C语言中的字符串转数字函数常见问题详解 字符串转整形 atoi函数 字符串转长整形 strtol函数, C语言中的字符串转数字函数常见问题详解 字符串转整形 atoi函数 函数原型: int a ...
- MediaInfo源代码分析 4:Inform()函数
===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...
- MediaInfo源代码分析 2:API函数
===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...
- MediaInfo源代码分析 3:Open()函数
===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...
- c语言fputc输入字符串,C语言fgetc和fputc函数用法详解(以字符形式读写文件)
C语言fgetc和fputc函数用法详解(以字符形式读写文件),文件,字符,指针,函数,字节 C语言fgetc和fputc函数用法详解(以字符形式读写文件) 易采站长站,站长之家为您整理了C语言fge ...
- 【Python入门】Python字符串的45个方法详解
Python中字符串对象提供了很多方法来操作字符串,功能相当丰富.必须进行全面的了解与学习,后面的代码处理才能更得心应手,编程水平走向新台阶的坚实基础.目前一共有45个方法,给大家分类整理,可以收藏查 ...
- PointNet系列代码复现详解(1)—PointNet分类部分
想尽快入门点云,因此就从这个经典的点云处理神经网络开始.源码已经有了中文注释,但在一些对于自己不理解的地方添加了一些注释.欢迎大家一起讨论. 代码是来自github:GitHub - yanx27/P ...
- ioctl 函数 参数 详解
2019独角兽企业重金招聘Python工程师标准>>> ioctl 函数 参数 详解 2009-04-24 11:55 ioctl函数 本函数影响由fd参数引用的一个打开的文件. # ...
最新文章
- Gitlab+Gerrit+Jenkins完整对接
- java 通配符 泛型_java中泛型之类型通配符(?)
- java做直播需要哪些技术_直播APP开发中需要解决哪些技术难点?千联信息
- 【笔记】Comparison of Object Detection and Patch-Based Classification Deep Learning Models on Mid- to La
- 华农c语言计算高精度加法_考研计算机 | 运算符与表达式算术运算符
- javascript闭包,你大爷永远是你大爷
- 使用Boxfuse轻松在云中运行Spring Boot应用程序
- 外设驱动库开发笔记4:AD9833函数发生器驱动
- 微信支付小年上线“点鞭炮,响优惠”活动 大额提现免费券限时发放
- 基于JAVA+SpringMVC+Mybatis+MYSQL的体育竞赛比赛赛事管理系统
- Netty in action—单元测试
- ABBYY FineReader PDF for Mac(PDF转换工具)
- HTML5应用——欢乐老虎机
- 从网络安装debian到使用中遇到的问题
- 2020中级计算机工程师,2020年上半年中级网络工程师报考详解
- c++ 解析纯真IP数据库qqwry
- 黑马12月开班时间出炉!戳文章免费试学!
- 苹果怎么设置铃声?设置自己喜欢的歌曲作为铃声,一招搞定!
- 【类不类三】来自星星的哥顿人与正则表达式
- 解决‘parent.relativePath‘ of POM xxx points at yyy instead of zzz please verify your project structure
热门文章
- php不可执行会怎样,从PHP运行可执行文件而不会产生shell
- oracle外部表使用详解,详解Oracle外部表的一次维护(图文)
- python生成试卷制卷系统_Python 读写文件 小应用:生成随机的测验试卷文件
- 【机器视觉案例】(5) AI视觉,远程手势控制虚拟计算器,附python完整代码
- 全国计算机建模三等奖,2009年全国数学建模真题(论文获国家 三等奖).doc
- java程序员可以只用windos吗_程序员要写多少代码 才能开发一个window操作系统
- python数据分析面试_python数据分析面试
- 二十岁出头的时候上,你一无所有,你拥有一切
- java c 解决方案_Java jdk安装及javac命令无效解决方案
- VSCode设置折叠左侧资源管理器所有文件夹的快捷键Alt+X、切换左侧活动栏显示隐藏快捷键Alt+Q