gpt4 book ai didi

perl - 如何在没有硬编码循环的情况下创建多个列表的组合?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:45:39 26 4
gpt4 key购买 nike

我有这样的数据:

    my @homopol = (
["T","C","CC","G"], # part1
["T","TT","C","G","A"], #part2
["C","CCC","G"], #part3 ...upto part K=~50
);


my @prob = ([1.00,0.63,0.002,1.00,0.83],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02]);


# Note also that the dimension of @homopol is always exactly the same with @prob.
# Although number of elements can differ from 'part' to 'part'.

我想做的是

  1. 生成 part1partK 中的所有元素组合
  2. @prob中对应元素的乘积。

因此最后我们希望得到这样的输出:

T-T-C  1 x 0.72 x 1 = 0.720
T-T-CCC 1 x 0.72 x 0.97 = 0.698
T-T-G 1 x 0.72 x 0.02 = 0.014
...
G-G-G 1 x 0.85 x 0.02 = 0.017
G-A-C 1 x 1 x 1 = 1.000
G-A-CCC 1 x 1 x 0.97 = 0.970
G-A-G 1 x 1 x 0.02 = 0.020

问题是我的以下代码是通过硬编码实现的循环。由于 @homopol 的部分数量可以变化并且很大(例如~K=50),我们需要一种灵活而紧凑的方式来获得相同的结果。有没有?我想用 Algorithm::Loops ,但不确定如何实现。

use strict;
use Data::Dumper;
use Carp;


my @homopol = (["T","C","CC","G"],
["T","TT","C","G","A"],
["C","CCC","G"]);


my @prob = ([1.00,0.63,0.002,1.00,0.83],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02]);



my $i_of_part1 = -1;
foreach my $base_part1 ( @{ $homopol[0] } ) {
$i_of_part1++;
my $probpart1 = $prob[0]->[$i_of_part1];

my $i_of_part2 =-1;
foreach my $base_part2 ( @{ $homopol[1] } ) {
$i_of_part2++;
my $probpart2 = $prob[1]->[$i_of_part2];

my $i_of_part3 = -1;
foreach my $base_part3 ( @{ $homopol[2] } ) {
$i_of_part3++;
my $probpart3 = $prob[2]->[$i_of_part3];

my $nstr = $base_part1."".$base_part2."".$base_part3;
my $prob_prod = sprintf("%.3f",$probpart1 * $probpart2 *$probpart3);

print "$base_part1-$base_part2-$base_part3 \t";
print "$probpart1 x $probpart2 x $probpart3 = $prob_prod\n";

}
}
}

最佳答案

我会推荐 Set::CrossProduct ,这将创建一个迭代器来生成所有集合的叉积。因为它使用了迭代器,所以不需要预先生成每一个组合;相反,它会按需生成每一个。

use strict;
use warnings;
use Set::CrossProduct;

my @homopol = (
[qw(T C CC G)],
[qw(T TT C G A)],
[qw(C CCC G)],
);

my @prob = (
[1.00,0.63,0.002,1.00],
[0.72,0.03,1.00, 0.85,1.00],
[1.00,0.97,0.02],
);

# Prepare by storing the data in a list of lists of pairs.
my @combined;
for my $i (0 .. $#homopol){
push @combined, [];
push @{$combined[-1]}, [$homopol[$i][$_], $prob[$i][$_]]
for 0 .. @{$homopol[$i]} - 1;
};

my $iterator = Set::CrossProduct->new([ @combined ]);
while( my $tuple = $iterator->get ){
my @h = map { $_->[0] } @$tuple;
my @p = map { $_->[1] } @$tuple;
my $product = 1;
$product *= $_ for @p;
print join('-', @h), ' ', join(' x ', @p), ' = ', $product, "\n";
}

关于perl - 如何在没有硬编码循环的情况下创建多个列表的组合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1442965/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com