mysql 多重循环_perl多重循环生成全排列精简

我想输出ATCG四个字符,组成一个12个字符长度字符串的全排列。共4^12=16777216种排列,

AAAAAAAAAAAA

AAAAAAAAAAAT

AAAAAAAAAAAC

AAAAAAAAAAAG

AAAAAAAAAATA

`````````````````````````

按照正常的想法是通过多重循环来生成全排列,所以我写下了下面这样的代码,但是有个问题,它不支持多扩展性,如果100个全排列,那么得写一百次循环嵌套。

cc15ecfbbfa4714335c99304e1c60149.png

所以我求助了perl-china群里的高手,其中一个给了一个结合二进制的巧妙解决方案。

perl -le '{$a{"00"}="A";$a{"01"}="T";$a{"10"}="C";$a{"11"}="G";for(0..100){print join"",map{$a{$_}} unpack("a2"x12,sprintf("%024b\n",$_))}}'

AAAAAAAAAAAA

AAAAAAAAAAAT

AAAAAAAAAAAC

AAAAAAAAAAAG

AAAAAAAAAATA

AAAAAAAAAATT

AAAAAAAAAATC

AAAAAAAAAATG

AAAAAAAAAACA

AAAAAAAAAACT

AAAAAAAAAACC

AAAAAAAAAACG

AAAAAAAAAAGA

AAAAAAAAAAGT

AAAAAAAAAAGC

AAAAAAAAAAGG

AAAAAAAAATAA

AAAAAAAAATAT

这里我简单解释一下这个代码

perl -le '{$a=sprintf("%024b\n",1);print $a}'

000000000000000000000001

这个sprintf是根据024b的格式把我们的十进制数字转为二级制,但是补全为24位。

perl -le '{@a=unpack("a2"x12,sprintf("%024b\n",100));print join":", @a}'

00:00:00:00:00:00:00:00:01:10:01:00

unpack这个函数很简单,就是把二进制的数值拆分成字符串数组,两个数字组成一个字符串。

最后通过map把$a{"00"}="A";$a{"01"}="T";$a{"10"}="C";$a{"11"}="G";对应成hash值并且输出即可!

然后这个大神又提成了一个递归的办法来解决

[perl]

#!/usr/bin/perl

my $arr = [];

$arr->[$_] = 0 for (0..11);

my @b = ("A","C","G","T");

while(1){

print join "", map {$b[$_]} @$arr;

print "\n";

exit unless &count($arr,11);

}

sub count {

my $arr = shift;

my $x = shift;

return 0 if $x < 0;

if ($arr->[$x] < 3){

$arr->[$x]++;

return 1;

}

else{

$arr->[$x] = 0;

return &count($arr,$x - 1);

}

}

[/perl]

还有另外一个大神也提成了一个递归的算法解决,算法之道还是蛮有趣的

5a6964d0fd69eb8034db1e18604e6ae5.png

最后还补充一个也是计算机技巧的解决方案,也是群里的朋友提出来的。

[perl]

#!/usr/bin/perl -w

my @A = qw(A T G C);

my $N = 12;

foreach my $n (0..4**$N){

foreach my $index (0..$N){

print $A[$n%4];

$n = $n >>2;

}

print "\n";

}

[/perl]

这个是位运算,如果C语言基础学的好的同学很快就能看懂的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值