-2

私はPerlを初めて使用します。最近、2 つの構造間の原子間の相関係数を計算するコードを書きました。これは私のプログラムの簡単な要約です。

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

このプログラムは、すべての相関関係を 1 つの列に連続して出力します。しかし、相関関係を行列の形で出力する必要があります..

         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 対応スプレッドシート プログラム (OpenOffice) で適切なテーブルに簡単に読み取ることができます。選択したスプレッドシート ビューアーがタブを区切りとして認識できない場合は、簡単に ; を追加できます。または/またはprintf文字列に使用できるものは何でも。

于 2013-11-14T14:29:52.787 に答える
0

あなたが抱えている単純な問題。行の印刷が終了したら、NL を印刷する必要があります。しかし、私があなたの注意を引いている間、私はおしゃべりを続けます。

参照を使用して、データを行列に保存する必要があります。このように、データを保存する方法は、データの概念と一致します。

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.

私の好みは2番目の方法です。これは実際にはマトリックスではないことを簡単に思い出してください。代わりに、それは私の行の配列であり、各行その特定の行のデータを保持する別の配列を指しています。最初の方法ほどきれいではありませんが、構文はまだかなりきれいです。

さて、あなたの問題に戻りましょう:

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 スタイルの 3 つの部分よりも簡潔です。(Python にはありません。Perl 6 でサポートされるかどうかはわかりません)。これは非常に理解しやすいです。配列をインクリメントしています。また、配列$#atomの長さ、またはマトリックスの行数も使用します。@atomsこのように、行列のサイズが変化しても、プログラムを編集する必要はありません。

[$j]少しトリッキーです。$atom[$i]は、行の列データを含む配列への参照であり、$i実際にはデータの行を直接表しているわけではありません。$atoms[$i]->[$j](これが、私が の代わりに好きな理由$atoms[$i][$j]です。この微妙なリマインダーを与えてくれます。) row の列データを含む実際の配列を取得するには、$iそれを逆参照する必要があります。したがって、実際の列の値は$i、配列 array の行に格納され@{$atoms[$i]}ます。

配列の最後のエントリを取得するには、@記号をに置き換えます。したがって、 配列$#の最後のインデックスは です。
$#{ $atoms[$i] }

ああ、これは真の行列ではないため、別のことです。各行には異なる数のエントリがある可能性があります。実際のマトリックスではそれを行うことはできません。これにより、Perl での配列の配列の使用が少し強力になり、少し危険になります。一貫した数の列が必要な場合は、手動で確認する必要があります。$j真のマトリックスは、最大値に基づいて必要な列を自動的に作成します。

于 2013-11-14T15:50:56.760 に答える