-2

我对 Perl 很陌生。最近我写了一个代码来计算两个结构之间的原子之间的相关系数。这是我的程序的简要总结。

for($i=1;$i<=2500;$i++)
{
    for($j=1;$j<=2500;$j++)
    {
         calculate the correlation (Cij);
         print $Cij;
    }
}

该程序在单个列中连续打印所有相关性。但是我需要以矩阵的形式打印相关性,例如..

         Atom1    Atom2   Atom3    Atom4
Atom1     0.5     -0.1     0.6      0.8
Atom2     0.1      0.2     0.3     -0.5
Atom3    -0.8      0.9     1.0      0.0
Atom4     0.3      1.0     0.8     -0.8

我不知道,它是怎么做到的。请帮助我解决方案或建议我如何去做!

4

2 回答 2

0

免责声明:伪代码,您可能需要自己处理特殊情况,尤其是标头。

for($i=1;$i<=2500;$i++)
{
print "\n";  # linebreak here.
    for($j=1;$j<=2500;$j++)
    {
        calculate the correlation (Cij);
        printf "\t%4f",$Cij;  # print a tab followed by your float giving it 4
                              # spaces of room. But no linebreak here.
    }
}

这当然是一个非常粗糙、快速和肮脏的解决方案。但是,如果您将输出保存到 .csv 文件中,大多数支持 csv 的电子表格程序 (OpenOfice) 应该能够轻松地将其读入适当的表格中。如果您选择的电子表格查看器无法将制表符理解为分隔符,您可以轻松添加;或 / 或任何可以用于 printf 字符串的内容。

于 2013-11-14T14:29:52.787 回答
0

你遇到的简单问题。完成打印一行后,您需要打印一个 NL。但是,当我引起你的注意时,我会继续闲聊。

您应该使用references将数据存储在矩阵中。这样,您存储数据的方式与数据的概念相匹配:

my @atoms;       # Storing the data in here
my $i = 300;
my $j = 400;

my $value = ...; # Calculating what the value should be at column 300, row 400.

# Any one of these will work. Pick one:

my $atoms[$i][$j] = $value;    # Looks just like a matrix!
my $atoms[$i]->[$j] = $value;  # Reminds you this isn't really a matrix.
my ${$atoms[$1]}[$j] = $value; # Now this just looks ridiculous, but is technically correct.

我的偏好是第二种方式。这只是一个轻微的提醒,这实际上不是一个矩阵。相反,它是我的行数组,每一行都指向另一个数组,该数组保存该特定行的数据。尽管不如第一种方式那么干净,但语法仍然很干净。

现在,让我们回到您的问题:

my @atoms;  # I'll store the calculated values here

....

my $atoms[$i]->[$j] = ... # calculated value for row $i column $j

....

# And not to print out my matrix

for my $i (0..$#atoms) {
    for my $j (0..$#{ $atoms[$i] } ) {
       printf "%4.2f  ", $atoms[$i]->[$j];  # Notice no "\n".
    }
    print "\n";    # Print the NL once you finish a row
}

注意我使用for my $i (0..$#atoms). 这种语法比for不鼓励使用的 C 风格的三部分更干净。(Python 没有,我不知道 Perl 6 会支持它)。这很容易理解:我正在增加我的数组。我还使用$#atomwhich 是我的@atoms数组的长度——或者我的矩阵中的行数。这样,随着矩阵大小的变化,我不必编辑我的程序。

列有点诡计 是对包含我的 row 列数据的数组的引用,并不真正直接代表一行数据。(这就是为什么我喜欢而不是。它给了我这个微妙的提醒。)要获取包含我的列数据的实际数组 row ,我需要取消引用它。因此,实际列值存储在数组 array的行中。[$j]$atom[$i]$i$atoms[$i]->[$j]$atoms[$i][$j]$i$i@{$atoms[$i]}

要获取数组中的最后一个条目,请将@sigil替换为 ,因此我的 数组中$#的最后一个索引是。
$#{ $atoms[$i] }

哦,另一件事,因为这不是一个真正的矩阵:每一行可能有不同数量的条目。你不能用真正的矩阵来做到这一点。这使得在 Perl 中使用 Array of Arrays 更加强大,也更加危险。如果您需要一致的列数,则必须手动检查。真正的矩阵会根据最大值自动创建所需的列$j

于 2013-11-14T15:50:56.760 回答