レポート課題5 ゲノム配列のreverse strand

ACGTからなるゲノム配列 s を表すクラスGenomeSequenceを実装し、配列の相補鎖(complement)を求めるメソッドgetComplementと、逆相補鎖(reverse complement)を返すメソッドgetReverseComplementを実装せよ。

相補鎖

配列の各文字を以下のように変換すると相補鎖が求められる。

A -> T
T -> A
G -> C
C -> G

逆相補鎖はさらに相補鎖を逆順に並べ替えたもの。

配列       ATGCGT
相補鎖     TACGCA
逆相補鎖   ACGCAT

GenomeSequence.java

public class GenomeSequence {
   private String sequence;

   public GenomeSequence(String sequence) {
      this.sequence = sequence;
   }
   public String getSequence() {
      return sequence;
   }

   public String getComplement() {
       // TODO 実装
       return null;
   }

   public String getReverseComplement() {
       // TODO 実装
       return null;
   }
}

テストコード GenomeSequenceTest.java

import static org.junit.Assert.*;
import org.junit.Test;

public class GenomeSequenceTest {

  @Test
  public void testGenomeSequence() {
    GenomeSequence s = new GenomeSequence("ACGT");
  }

  @Test
  public void testGetSequence() {
    GenomeSequence s = new GenomeSequence("ACGT");
    assertEquals("ACGT", s.getSequence());
  }

  @Test
  public void testComplement() {
    GenomeSequence s = new GenomeSequence("ATGCGT");
    assertEquals("TACGCA", s.getComplement());
  }

  @Test
  public void testReverseStrand() {
    GenomeSequence s = new GenomeSequence("ATGCGT");
    assertEquals("ACGCAT", s.getReverseComplement());
  }
}

注意: 文字列の並び替え

文字列の並び替えを行うときに+演算を使うと非常に効率が悪い。

たとえば、以下の命令は、

s += "A";
 s += "C";

内部では次のように実行されている。

StringBuilder tmp = new StringBuilder();
tmp.append(s);
tmp.append("A");
s = tmp.toString();

StringBuilder tmp2 = new StringBuilder();
tmp2.append(s);
tmp2.append("C");
s = tmp.toString();

配列s全体のコピー(append)が2回も発生しているため、無駄が多い。

効率を上げるために、最初からStringBuilderを使うとよい。

StringBuilder buf = new StringBuilder();
buf.append("A");
buf.append("C");
...
String result = buf.toString();