今天在论坛上看到有人问任意位数的排列组合的最简单代码该怎么写。看到很多人积极的回答,也有好多不错的代码,于是自己不仅也想凑个热闹。如果是以前,一定是循环套循环。但是无论怎么套,也没办法想要几位的就输出几位的。现在终于可以实现了。代码如下:
任务要求:0..9,a..z 全排列,按指定位数输出结果;
用到的知识:map & map嵌套;splice;
详细内容:
格式:map 表达式 列表;
map函数将列表按照表达式逐一运算,然后把结果输到一个新列表中。表达式中可以用多个语句,而且map可以套map哦~ ;P
格式:splice 列表1 起始位置 替换长度 列表2;
splice函数将从列表1的第N个起始位置开始,用列表2对列表1中的元素进行替换,替换的长度为设定的长度。
如果起始位为负数,则从数组的后面开始向前执行。
如果列表2长度不足设定长度,则列表1后面的元素前移。
如果列表2长度超过设定长度,则列表1的元素向后移。
如果长度为0,则相当于插入元素。
如果不设定列表2,则效果等同于删除起始位后面的元素。
活用map和splice函数将给程序带来意向不到的效果~O(∩_∩)O
程序代码:
#!perl
use strict; use warnings; my $n=$ARGV[0];#参数为要的位数!
my @out = my @main=(0..9,'a'..'z'); for (1..$n-1){ my @temp = map {my $t=$_;map {"$t"."$_"} @main} @out; splice(@out,0,@out,@temp); } print "@out";
|
OK了。不知道算不算最简,但是至少功能是都实现了,应该也不算太长吧~
呵呵~
(2009-10-11)
补充:在论坛上看到后续的回复中有更好的方法,速度更快。竟指点得知我的方法里有好多无意义的地方浪费了时间。比如splice……其实数组相互赋值根本用不上它。$t=$_赋值的时候也要消耗时间。而我想在下面的代码里可能是因为全部只用了引用,所以省略了大量的赋值时间。为了保留学到的知识点,上面的就不更改了。下面把论坛里更快的方法贴上。算4位的时候,我上面的代码要10几秒,而下面不到3秒就有结果了。强!学习了!
用到的知识:函数的嵌套,引用
程序代码:
my @arr=(0..9,'a'..'z'); my $num=4; our $data; func(\@arr,$num-1,''); #print @$data;
sub func{ my ($arr,$n,$sar)=@_; if($n==0){ push @$data,$sar.$_ for @$arr; return; } &func($arr,$n-1,$sar.$_) for @$arr; }
|
(2009-10-12)
by banban
阅读(1885) | 评论(0) | 转发(0) |