php源码str_repeat有趣的实现
来源:互联网 发布:淘宝小二有什么用 编辑:程序博客网 时间:2024/06/06 02:48
今天在翻看php源码时, 研究了一下str_repeat
的实现. 算法很有意思, 一般人的思路都是字符串拼接, 重复n次,就拼接n次, 时间复杂度为O(n). 但作者的思路很有意思, 把时间复杂度降到了log2^n+1.
上代码:
PHP_FUNCTION(str_repeat){ zend_string *input_str; /* Input string */ zend_long mult; /* Multiplier */ zend_string *result; /* Resulting string */ size_t result_len; /* Length of the resulting string */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sl", &input_str, &mult) == FAILURE) { return; } if (mult < 0) { php_error_docref(NULL, E_WARNING, "Second argument has to be greater than or equal to 0"); return; } /* Don't waste our time if it's empty */ /* ... or if the multiplier is zero */ if (ZSTR_LEN(input_str) == 0 || mult == 0) RETURN_EMPTY_STRING(); /* Initialize the result string */ result = zend_string_safe_alloc(ZSTR_LEN(input_str), mult, 0, 0); result_len = ZSTR_LEN(input_str) * mult; /* Heavy optimization for situations where input string is 1 byte long */ if (ZSTR_LEN(input_str) == 1) { memset(ZSTR_VAL(result), *ZSTR_VAL(input_str), mult); } else { char *s, *e, *ee; ptrdiff_t l=0; memcpy(ZSTR_VAL(result), ZSTR_VAL(input_str), ZSTR_LEN(input_str)); s = ZSTR_VAL(result); //猜测这里的变量名为start e = ZSTR_VAL(result) + ZSTR_LEN(input_str); //这里应该是end ee = ZSTR_VAL(result) + result_len; //这里应该是end ending, 最后的结尾 //重点看这里, 整个算法的核心 while (e<ee) { //判断剩余内存的大小是否大于已经复制的内存大小, 取小者 l = (e-s) < (ee-e) ? (e-s) : (ee-e); memmove(e, s, l); e += l; } } ZSTR_VAL(result)[result_len] = '\0'; RETURN_NEW_STR(result);}
内存图:
第一次循环:
因为e-s < ee-e, 所以l取e-s, 也就是1
第二次循环:
因为e-s < ee-e, 所以l取e-s, 也就是2
第三次循环:
因为e-s > ee-e, 所以l取ee-e, 也就是2
第四次循环:
l=0
阅读全文
0 0
- php源码str_repeat有趣的实现
- PHP中的str_repeat函数JavaScript实现
- PHP str_repeat() 函数
- 有趣的c++源码
- 有趣的PHP ++ 益智题
- 有趣的php益智题
- php 有趣的头像拼图
- php中有趣的编程
- 有趣的冒泡排序实现
- 有趣的累加求和实现
- css | 实现有趣的多边形
- PHP实现文件上传的程序源码
- php源码分析trim函数的实现
- PHP源码之数组的内部实现
- PHP源码之数组的内部实现
- PHP源码之数组的内部实现
- PHP的一些有趣的算法
- 对于有趣的php引用的探索
- Java 循环结构
- 关于上传图片插件webuploader的使用(同一个页面存在多个实例):
- maven学习笔记:20170606
- 以太坊(3):以太坊私有链环境下的智能合约的编写、编译、创建与执行
- 【线程间同步】Android线程之间如何进行同步
- php源码str_repeat有趣的实现
- JEESITE登录流程简单梳理
- Android蓝牙开发(二)
- oracle数据库导出
- 自动管理的花园
- Ubuntu 虚拟主机Django部署全代码
- #Android开发之kotlin实现(体验)
- IDCard识别
- hdu