これらすべての組み合わせを望んでいますが、メモリが不足しています。スクリプトからメモリを解放するには?
use strict;
use warnings;
use Algorithm::Combinatorics 'variations_with_repetition';
my @let = qw/ A G C T /;
my @cad = variations_with_repetition(\@let, 24);
print "@$_\n" for @cad;
答え1
解決策は単にを使用することですiterators
。結果をvariations_with_repetition
スカラーに割り当てると、次の要素を取得するために毎回クエリできるイテレータが生成されます。これにより、リスト全体をメモリに保存する必要がなくなり、最初の要素にすぐにアクセスできます。という素敵なコンセプトです。怠惰な評価。あなたのケースのコードは次のとおりです。
use strict;
use warnings;
use Algorithm::Combinatorics 'variations_with_repetition';
my @let = qw / A G C T/;
my $cad = variations_with_repetition(\@let,24);
while(my $c = $cad->next)
{
print "@$c\n";
}
イテレータは実際に配列への参照を返します。まず、これを逆参照してから組み合わせるか、必要な操作を実行する必要があります。
テスト結果:私は私のコンピュータで初期コードを実行することはできませんでした(メモリの使用量は予想通り無限に増加しました)、Perlはメモリをほとんど消費しない間、イテレータを使用してすぐに出力ラインを取得し始めました。
答え2
まあ、アルファベット(A、G、C、T)で単語を列挙することは、4進法で数字を数えるのと非常に似ています。これに注意してください(ヘッドへの呼び出しを削除してください。テストすると非常に長い出力が切り捨てられます)。
{ echo 4o; seq 0 $((4 ** 24 - 1)) | sed 's/$/p/'; } | dc | awk '{ printf "%024d\n", $1 }' | tr 0-4 AGCT | head
説明する:
echo 4o
dc
4進数で出力を表すコマンドです。seq
24桁の4進数の全範囲を計算する必要があります。sed
各行に1を追加します。各番号を印刷するp
必要があります(基本4を覚えておいてください)。dc
awk
数字が24桁を印刷する前にゼロを十分に追加します。tr
数値(0、1、2、3)を文字(A、G、C、T)に変換します。