xuekai0 2010-07-19
本文和大家重点讨论一下Perl关联数组和哈希表的概念,Perl关联数组,又称为哈希表(hashtable),是一种非常好用的数据结构。希望通过本文的介绍你对Perl关联数组的概念有深入的了解。
Perl关联数组和哈希表
Perl关联数组,又称为哈希表(hashtable),是一种非常好用的数据结构。
在程序中,我们可能会遇到需要消重的问题,举一个最简单的模型:
有一份用户名列表,存储了10000个用户名,没有重复项;
还有一份黑名单列表,存储了2000个用户名,格式与用户名列表相同;
现在需要从用户名列表中删除处在黑名单里的用户名,要求用尽量快的时间处理。
这个问题是一个小规模的处理量,如果实际一点,2个表都可能很大,比如有2亿条记录。
我最开始想到的方法,就是做一个嵌套的循环,设用户名表有M条记录,黑名单列表有N条记录,那么,循环的次数是M*N次!
PHP版代码:
<?php foreach($arrayMas$keyM=>$nameM){ foreach($arrayNas$nameN){ if($nameM==$nameN){ //本行执行了M*N次! unset($arrayM[$keyM]); } } } return$arrayM; ?>
另一种方式,利用数组索引。
PHP是一种弱类型的语言,不像C语言那样有严格的变量类型限制。C语言的数组,每一个元素的类型必须一致,而且索引都是从0开始。
PHP的数组,可以用字符串作为索引,也称为Perl关联数组。
数组索引,有一个天然的限制就是不会重复,而且访问的时候不需要查找,可以直接定位。
还是刚才的那个问题,我们采用另一种办法。
把黑名单列表的用户名组织到一个数组里,数组的索引就是用户名。
然后,遍历用户列表的时候,只需直接用isset查询那个用户名是否存在即可。
PHP版代码:
<?php $arrayarrayHash=array(); foreach($arrayNas$nameN){ //本行执行了N次。 $arrayHash[$nameN]=1; } foreach($arrayMas$keyM=>$nameM){ if(isset($arrayHash[$nameM])){ //本行执行了M次! unset($arrayM[$keyM]); } } return$arrayM; ?>
可以看到,优化过的代码,循环次数是M+N次。
假如M和N都是10000,优化前,循环了1亿次;优化后,只循环了20000次,差了5000倍!
如果第二个程序耗时1秒,则第一个程序需要将近一个半小时!
最近在做Perl的开发,Perl在处理文本的时候有很高的效率,同样,它也支持Perl关联数组!
只是语法和PHP的那种类C的方式有很大不同,以第二段代码为例,Perl版的实现:
#!/usr/bin/perl my%arrayHash; for(my$i=0;$i<@arrayN;++$i){ $arrayHash{$arrayN[$i]}=1; } for(my$i=0;$i<@arrayM;++$i){ if($arrayHash{$arrayM[$i]}){ $arrayM[$i]=undef; } }
Perl关联数组是@开头,哈希是以%开头,unset实际上就是undef。
Perl的哈希和数组都是有具体类型的,而且向函数传递变量的时候要传引用,我刚学时间不长,快被搞晕了。