今天做 Google的 Code Jam 上的一道题目:https://code.google.com/codejam/contest/351101/dashboard#s=p2,用Perl语言解答的。遇到一个关于hash遍历的问题,思考了好一会儿才发现问题所在,为了简化叙述,写了一个简单的遍历哈希表的Perl程序如下:

  

  

   #!/usr/bin/perl
my %hash=(
=>"a",
=>"b",
=>"c",
=>"d",
=>"e",
=>"f",
=>"g",
=>"h",
=>"i",
=>"j",
);
for(keys %hash){
print "$_ => $hash{$_}\n";
}
my $times;
for(my $i=;$i<=;$i++){
$times=;
print "====================Loop No.$i:=====================\n";
LOOP1: while(my ($key,$value)=each %hash){
$times++;
print "\t'$key'=>'$value'\n";
if ($times>=){
last LOOP1;
}
}
}

该程序 2 ~ 13 行先建立了一个哈希表,然后遍历输出这个哈希表。

接下来的 18 ~ 28 行,用 while 循环和哈希表的 each 函数遍历该哈希表,用 for 循环控制遍历四次,每次遍历只遍历两个哈希表中的值。按照设想,这四次的遍历应当输出同样的内容,但输出如下:

 => f
=> c
=> g
=> i
=> b
=> h
=> a
=> d
=> j
=> e
====================Loop No.:=====================
'6'=>'f'
'3'=>'c'
====================Loop No.:=====================
'7'=>'g'
'9'=>'i'
====================Loop No.:=====================
'2'=>'b'
'8'=>'h'
====================Loop No.:=====================
'1'=>'a'
'4'=>'d'

由结果可以看出,这四次的输出并非都是一样的,这说明,用 while 循环 + each 函数遍历哈希表的时候,如果提前跳出了while循环,那么下次再接着用 each 函数遍历该哈希表的时候,会从上次已经遍历过的关键字的下一个关键字处开始遍历。

如果将 while 循环改成 for 或 foreach 循环呢?(Perl 中 for 和 foreach 其实是等价的):

   #!/usr/bin/perl
my %hash=(
=>"a",
=>"b",
=>"c",
=>"d",
=>"e",
=>"f",
=>"g",
=>"h",
=>"i",
=>"j",
);
for(keys %hash){
print "$_ => $hash{$_}\n";
}
my $times;
for(my $i=;$i<=;$i++){
$times=;
print "========== Loop No.$i ==========\n";
foreach(my ($key,$value)=each %hash){
$times++;
print "\t'$key'=>'$value' \tand times=$times\n";
}
}

输出结果如下:

 => f
=> c
=> g
=> i
=> b
=> h
=> a
=> d
=> j
=> e
========== Loop No. ==========
'6'=>'f' and times=
'6'=>'f' and times=
========== Loop No. ==========
'3'=>'c' and times=
'3'=>'c' and times=
========== Loop No. ==========
'7'=>'g' and times=
'7'=>'g' and times=
========== Loop No. ==========
'9'=>'i' and times=
'9'=>'i' and times=

每次 foreach 循环会遍历两次,而且并没有改变循环的关键字,有点奇怪啊...

Perl学习笔记(3)----遍历哈希表的一个容易疏忽的地方的更多相关文章

  1. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

  2. .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]

    原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...

  3. Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目

    Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目 Spring Tool Suite 是一个带有全套的Spring相关支持功能的Eclipse插件包. ...

  4. Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序

    Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...

  5. Perl 学习笔记-哈希

    1.Perl中的哈希 高效快捷, 没有大小限制. 大哈希一样很快! 命名: 和Perl其他标识符一样, 同时拥有自己的的名字空间.  $roger{"sex"} 和 $roger没 ...

  6. perl学习笔记——哈希

    哈希 哈希是一种数据结构,它和数组的相似之处在于可以容难任意多的值并能按需取用,而他和数组的不同在于索引的方式,数组是以数字为索引而哈希则是以名字为索引. 哈希的键是唯一的,哈希的值可以重复. 哈希的 ...

  7. perl 学习笔记

    一:基础 1:安装perl      centos: yum -y install perl       官网:https://www.perl.org/      升级到5.22:先下载,执行./i ...

  8. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  9. Django学习笔记(7)——单表操作和多表操作

    单表操作 1,创建模型 创建名为book的APP,在book下的models.py中创建模型: from django.db import models # Create your models he ...

随机推荐

  1. BZOJ1721 Ski Lift 缆车支柱

    Description Farmer Ron in Colorado is building a ski resort for his cows (though budget constraints ...

  2. python 控制台输出带颜色的文字的方法

    python_控制台输出带颜色的文字方法   在python开发的过程中,经常会遇到需要打印各种信息.海量的信息堆砌在控制台中,就会导致信息都混在一起,降低了重要信息的可读性.这时候,如果能给重要的信 ...

  3. 使用FFmpeg进行视频抽取音频,之后进行语音识别转为文字

    1.首先需要下载FFmpeg: 2.Gradle依赖 def void forceVersion(details, group, version) { if (details.requested.gr ...

  4. BZOJ 3437: 小P的牧场

    传送门 显然考虑 $dp$,设 $f[i]$ 表示前 $i$ 个牧场都被控制的最小代价 那么枚举所有 $j<i$ ,$f[i]=f[j]+val[i][j]+A[i]$ $val[i][j]$ ...

  5. 微信公共平台注册 bug: 验证码不应该输入后,就立即检查其有效性

    本文链接: https://www.cnblogs.com/hchengmx/p/10793037.html 刚刚想注册个微信公众号,就发现了这个问题,在这里记录一下. 已经发到testhome了,链 ...

  6. ionic3 pop到指定页面

    this.navCtrl.getViews().forEach(element => { if(element.name == 'JiecheHomePage'){ this.navCtrl.p ...

  7. VirtualBox 命令行操作

    vboxmanage list vmsvboxmanage list runningvmsvboxmanage startvmvboxmanage controlvm "RHEL6.1_fo ...

  8. 如何在cmd窗口里快速且正确打开任意位置路径(各版本windows系统都适合)(图文详解)(博主推荐)

    问题的由来 有时候,我们很苦恼,总是先系统键 + R,然后再去手动敲.尤其对win7系统比较麻烦 解决办法 方法一:复制路径(这点对win10系统做得好,直接可以复制) ,win7系统的话可能还需要设 ...

  9. 【ExtJS】 布局Layout

    布局用于定义容器如何组织内部子元素和控制子元素的大小. ExtJS中有两种类型的布局:Container容器类布局与Component组件类布局. Containter容器类布局:负责容器内容Extj ...

  10. D3介绍

    D3介绍 D3是用来做web页面可视化的组件,其官方网址为http://d3js.org 安装 D3类库的文件只有一个d3.js.下载后直接在html的<script>标签中引用此js就可 ...