-2

ヌクレオチド A、C、G、T を 0、1、2、3 として表しています。その後、4 進数を表すシーケンスを 10 進数に変換する必要があります。perlでこれを達成する方法はありますか? pack/unpack でこれができるかどうかはわかりません。

4

3 に答える 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 に答える