关联数组,又称为哈希表(hash table),是一种非常好用的数据结构。
在程序中,我们可能会遇到需要消重的问题,举一个最简单的模型:
有一份用户名列表,存储了 10000 个用户名,没有重复项;
还有一份黑名单列表,存储了 2000 个用户名,格式与用户名列表相同;
现在需要从用户名列表中删除处在黑名单里的用户名,要求用尽量快的时间处理。
这个问题是一个小规模的处理量,如果实际一点,2 个表都可能很大,比如有 2 亿条记录。
我最开始想到的方法,就是做一个嵌套的循环,设用户名表有 M 条记录,黑名单列表有 N 条记录,那么,循环的次数是 M * N 次!
PHP 版代码:
- <?php
- foreach($arrayM as $keyM => $nameM) {
- foreach($arrayN as $nameN) {
- if ($nameM == $nameN) {
- // 本行执行了 M * N 次!
- unset($arrayM[$keyM]);
- }
- }
- }
- return $arrayM;
- ?>
另一种方式,利用数组索引。
PHP 是一种弱类型的语言,不像 C 语言那样有严格的变量类型限制。C 语言的数组,每一个元素的类型必须一致,而且索引都是从 0 开始。
PHP 的数组,可以用字符串作为索引,也称为关联数组。
数组索引,有一个天然的限制就是不会重复,而且访问的时候不需要查找,可以直接定位。
还是刚才的那个问题,我们采用另一种办法。
把黑名单列表的用户名组织到一个数组里,数组的索引就是用户名。
然后,遍历用户列表的时候,只需直接用 isset 查询那个用户名是否存在即可。
PHP 版代码:
- <?php
- $arrayHash = array();
- foreach($arrayN as $nameN) {
- // 本行执行了 N 次。
- $arrayHash[$nameN] = 1;
- }
- foreach($arrayM as $keyM => $nameM) {
- if (isset($arrayHash[$nameM])) {
- // 本行执行了 M 次!
- unset($arrayM[$keyM]);
- }
- }
- return $arrayM;
- ?>
可以看到,优化过的代码,循环次数是 M + N 次。
假如 M 和 N 都是 10000,优化前,循环了 1 亿次;优化后,只循环了 20000 次,差了 5000 倍!
如果第二个程序耗时 1 秒,则第一个程序需要将近一个半小时!
原文地址:
http://hi.baidu.com/chenhaoxian/blog/item/5cc2222d8509e03d349bf7ac.html
转载于:https://blog.51cto.com/stanley1029/705592