揭秘Perl关联数组和哈希表联系

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;  



?&gt; 



 

另一种方式,利用数组索引。

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;  



?&gt; 



 

可以看到,优化过的代码,循环次数是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&lt;@arrayN;++$i){  



$arrayHash{$arrayN[$i]}=1;  


}  


 



for(my$i=0;$i&lt;@arrayM;++$i){  



if($arrayHash{$arrayM[$i]}){  


$arrayM[$i]=undef;  


}  


}  


 

Perl关联数组是@开头,哈希是以%开头,unset实际上就是undef。
Perl的哈希和数组都是有具体类型的,而且向函数传递变量的时候要传引用,我刚学时间不长,快被搞晕了。

相关推荐