Perl學習筆記(3)----遍歷哈希表的一個容易疏忽的地方


  今天做 Google的 Code Jam 上的一道題目:https://code.google.com/codejam/contest/351101/dashboard#s=p2,用Perl語言解答的。遇到一個關於hash遍歷的問題,思考了好一會兒才發現問題所在,為了簡化敘述,寫了一個簡單的遍歷哈希表的Perl程序如下:

  

  

  1 #!/usr/bin/perl
  2 my %hash=(
  3         1=>"a",
  4         2=>"b",
  5         3=>"c",
  6         4=>"d",
  7         5=>"e",
  8         6=>"f",
  9         7=>"g",
 10         8=>"h",
 11         9=>"i",
 12         0=>"j",
 13 );
 14 for(keys %hash){
 15         print "$_ => $hash{$_}\n";
 16 }
 17 my $times;
 18 for(my $i=1;$i<=4;$i++){
 19         $times=0;
 20         print "====================Loop No.$i:=====================\n";
 21 LOOP1:  while(my ($key,$value)=each %hash){
 22                 $times++;
 23                 print "\t'$key'=>'$value'\n";
 24                 if ($times>=2){
 25                         last LOOP1;
 26                 }
 27         }
 28 }

該程序 2 ~ 13 行先建立了一個哈希表,然后遍歷輸出這個哈希表。

接下來的 18 ~ 28 行,用 while 循環和哈希表的 each 函數遍歷該哈希表,用 for 循環控制遍歷四次,每次遍歷只遍歷兩個哈希表中的值。按照設想,這四次的遍歷應當輸出同樣的內容,但輸出如下:

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

由結果可以看出,這四次的輸出並非都是一樣的,這說明,用 while 循環 + each 函數遍歷哈希表的時候,如果提前跳出了while循環,那么下次再接着用 each 函數遍歷該哈希表的時候,會從上次已經遍歷過的關鍵字的下一個關鍵字處開始遍歷。

如果將 while 循環改成 for 或 foreach 循環呢?(Perl 中 for 和 foreach 其實是等價的):

  1 #!/usr/bin/perl
  2  my %hash=(
  3          1=>"a",
  4          2=>"b",
  5          3=>"c",
  6          4=>"d",
  7          5=>"e",
  8          6=>"f",
  9          7=>"g",
 10          8=>"h",
 11          9=>"i",
 12          0=>"j",
 13  );
 14  for(keys %hash){
 15          print "$_ => $hash{$_}\n";
 16  }
 17 my $times;
 18 for(my $i=1;$i<=4;$i++){
 19         $times=0;
 20         print "========== Loop No.$i ==========\n";
 21         foreach(my ($key,$value)=each %hash){
 22                 $times++;
 23                 print "\t'$key'=>'$value' \tand times=$times\n";
 24         }
 25 }

輸出結果如下:

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

每次 foreach 循環會遍歷兩次,而且並沒有改變循環的關鍵字,有點奇怪啊...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM