ヌクレオチド A、C、G、T を 0、1、2、3 として表しています。その後、4 進数を表すシーケンスを 10 進数に変換する必要があります。perlでこれを達成する方法はありますか? pack/unpack でこれができるかどうかはわかりません。
質問する
282 次
3 に答える
1
Base 4は正確に2ビットを必要とするため、効率的に処理するのは簡単です。
my $uvsize = length(pack('J>', 0)) * 8;
my %base4to2 = map { $_ => sprintf('%2b', $_) } 0..3;
sub base4to10 {
my ($s) = @_;
$s =~ s/(.)/$base4to2{$1}/sg;
$s = substr(("0" x $uvsize) . $s, -$uvsize);
return unpack('J>', pack('B*', $s));
}
これにより、32ビット整数をサポートするビルドでは16桁の入力が可能になり、64ビット整数をサポートするビルドでは32桁の入力が可能になります。
フローティングポイントを使用してわずかに大きい数をサポートすることが可能です。IEEEダブルを使用したビルドでは26、IEEEクワッドを使用したビルドでは56です。これには別の実装が必要になります。
それよりも大きい場合、Perl用のMath::BigIntなどのモジュールがそれらを格納する必要があります。
より速く、より簡単に:
my %base4to16 = (
'0' => '0', '00' => '0', '20' => '8',
'1' => '1', '01' => '1', '21' => '9',
'2' => '2', '02' => '2', '22' => 'A',
'3' => '3', '03' => '3', '23' => 'B',
'10' => '4', '30' => 'C',
'11' => '5', '31' => 'D',
'12' => '6', '32' => 'E',
'13' => '7', '33' => 'F',
);
sub base4to10 {
(my $s = $_[0]) =~ s/(..?)/$base4to16{$1}/sg;
return hex($s);
}
于 2012-09-20T21:14:40.237 に答える
1
私は一度も使用したことがありませんが、Convert::BaseN モジュールが適しているようです。 Convert::BaseN - base{2,4,8,16,32,64} 文字列のエンコードとデコード
于 2012-09-20T20:44:34.163 に答える
1
ループ内の各桁を処理することにより、基数 4 の文字列を 10 進数に計算するのは非常に簡単です。
32 ビット マシンでは、16 塩基を超える配列を表すことができないことに注意してください。
このコードはアイデアを示しています
use strict;
use warnings;
print seq2dec('ACGTACGTACGTACGT');
sub seq2dec{
my ($sequence) = @_;
my $n = 0;
for (map {index 'ACGT', $_} split //, $sequence) {
$n = $n * 4 + $_;
}
return $n;
}
出力
454761243
于 2012-09-20T21:07:25.183 に答える