如何随机打乱某组数据,并按任意键显示?-[结帖]

#!/usr/bin/perl

use strict;
my %hash=(
   '001'=>'张三',
   '002'=>'李四',
   '003'=>'王五',
   '004'=>'刘六',
   '005'=>'陈七',
);
my @pool=keys %hash;
my $i = @pool; # $i是数组的长度


for(@pool){
    print "Press ENTER key to continue!\nEnter 'exit' to exit the programme\n";
    exit if <>=~/exit/i;
my $n; #存放随机数


my $n = rand($i--);
print $pool[$n],": ",$hash{$pool[$n]}," win!\n";
$pool[$n] = $pool[$i];
}
print "Over! press Enter to exit!";
<>;

-------该程序满足我的抽签要求(一个学期内,让每个学生都有且仅有一次机会做即兴演,直到50名学生轮回完毕,此为一轮抽签。然后进行第2轮....每轮抽签的结果都是随机产生的)。
-------对该程序,偶有点不太明白:$pool[$n] = $pool[$i];该句的意思是将随机抽到的ID用最后一个ID替换。当$i--=5时,$n有可能随机恰好等于4,$i减一,此时$i=4,$ pool[$n]和$pool[$i]均等于005,也就是用005替换005,替换后005号依然存在@pool中,该轮中,005还会参加抽签,那如何保证005不会两次或多次被抽中呢?
-------小弟好糊涂阿,请老大耐心指点,感激不尽!谢谢!


QUOTE:
原帖由 windows.li 于 2007-12-12 13:31 发表
#!/usr/bin/perl

use strict;
my %hash=(
   '001'=>'张三',
   '002'=>'李四',
   '003'=>'王五',
   '004'=>'刘六',
  &nb ...

呵呵,他用了很巧妙的方法,在于如何理解这个rand的使用,每次rand($i--),取得的值都会小于$i
并不在于rand($i--)是否等于$i-1,即使等于,下一次,也是取不到的,因为最后一位的数据被rand放弃了(可以这么理解)
所以,每次都需要把最后一个数据读到被“取出删除”(实际上是中奖者)的地方,这样就不会重复也不会浪费了
当然,这个数组在这里是无法重复使用的

我倒是想问lonki兄,如何生成随机序列,这个貌似没弄过
hash的随机序列是固定的,最多相当于随机一次……

-------对该程序,偶有点不太明白:$pool[$n] = $pool[$i];该句的意思是将随机抽到的ID用最后一个ID替换。当$i--=5时,$n有可能随机恰好等于4,$i减一,得到$i=4,此时$pool[$n]=$pool[4]=005,$pool[$i]=$pool[4]=005,也就是用005替换005,替换后005号依然存在@pool中,该轮中,005还会参加抽签,那如何保证005不会两次或多次被抽中呢?

上面的分析哪句有错?请挑下,谢谢您!困惑中...

沒錯,你的分析基本上沒錯,關鍵在rand()函數,
拿你的例子來說, 雖然"005"依然在@pool中,但
 rand(4) 生成的數可能為 0, 1, 2, 3
  所以存放"005"的$pool[4]是肯定不會再被抽中的.
拿笔一划,明白了!这几天都没怎么睡觉,黄昏阿,呵呵!
谢谢诸位。