이 모든 조합을 원하지만 메모리가 부족합니다. 스크립트에서 메모리를 확보하는 방법은 무엇입니까?
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진법으로 숫자를 세는 것과 매우 유사합니다. 이것을 알아두십시오(head에 대한 호출을 제거하십시오. 테스트할 때 매우 긴 출력이 잘립니다).
{ 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자리를 인쇄하도록 앞에 0을 충분히 추가합니다.tr
숫자(0, 1, 2, 3)를 문자(A, G, C, T)로 변환합니다.