交换字符串中的字母

时间:2010-07-15 09:46:33

标签: java

我需要用以下规则交换字符串中的字母:

  • A由T
  • 取代
  • T由A
  • 取代
  • C由G
  • 代替
  • G被C
  • 取代

例如:ACGTA应该成为TGCAT

解决此问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:9)

正在搜索java "A to T, T to A"找到此suggestion

String sequence = "AATTTCTCGGTTTCAAT";
sequence = sequence.replace("A", "t")
                   .replace("T", "a")
                   .replace("C", "g")
                   .replace("G", "c")
                   .toUpperCase();
System.out.println(sequence);

这是一个简单而简洁的解决方案,适用于您的特定情况,如果您的DNA字符串相对较短,将具有可接受的性能。对于处理大量数据的更通用的解决方案,您应该逐个迭代字符并构建新字符串。或者作为polygenelubricants指出 - 考虑一种存储格式,每个基数只使用2位而不是16位。

答案 1 :(得分:6)

我会选择这样一个更通用的解决方案:

public String tr(String original, String trFrom, String trTo) {
  StringBuilder sb = new StringBuilder();

  for (int i = 0; i < original.length(); ++i) {
    int charIndex = trFrom.indexOf(original.charAt(i));
    if (charIndex >= 0) {
      sb.append(trTo.charAt(charIndex));
    } else {
      sb.append(original.charAt(i));
    }
  }

  return sb.toString(); 
}

调用这样的函数会得到你需要的结果:

tr("ACGTA", "ATCG", "TAGC")

因此该函数与unix tr实用程序几乎相同:

echo ACGTA | tr ATCG TAGC

答案 2 :(得分:3)

与我explained yesterday一样,字符串是不可变的,你不能改变一个字符串,你必须创建一个新字符串并替换旧字符串。

您可以像这样解决问题:

String s = "ACGTA";
StringBuilder sb= new StringBuilder();
for (char c:s.toCharArray()) {
  switch(c) {
    case 'A': sb.append('T');break;
    case 'T': sb.append('A');break;
    case 'C': sb.append('G');break;
    case 'G': sb.append('C');break;
    default: //handle error here -> invalid char in String
  }
}
s = sb.toString();

这个解决方案的优点是你不会创建太多的String对象(每个'replace'操作都会创建一个新的String,如果你必须还原很多,这会破坏性能dna序列)


以下是基于polygenelubricantsrsp非常有用的评论的更高性能版本:

String s = "ACGTA";
char[] reverse = new char[s.length()];
for (int i = 0; i < reverse.length; i++) {
  switch(s.charAt(i)) {
    case 'A': reverse[i] = 'T';break;
    case 'T': reverse[i] = 'A';break;
    case 'C': reverse[i] = 'G';break;
    case 'G': reverse[i] = 'C';break;
    default: //handle error here -> invalid char in String
  }
}
s = new String(reverse);

答案 3 :(得分:0)

DNA有一个小字母表。您可以使用lookup table,使用简单的数组索引替换某些语句。

这种方法:

  • 仅遍历序列一次。
  • 取消条件陈述。
  • 在字母大小写方面可以保持稳定,有时用于传递DNA序列中的信息。
  • 可以处理IUPAC模糊代码。
  • 可以处理差距。
  • 可以轻松提供反向补充

首先,您需要一个查找表。

private static final String COMPLEMENT_TABLE 
  // 0123456789ABCDEF0123456789ABCDEF
  = "                                " // 0-31
  + "             -                  " // 32-63
  + " TVGH  CD  M KN   YSAABWXR      " // 64-95
  + " tvgh  cd  m kn   ysaabwxr      "; // 96-127
  //  ABCDEFGHIJKLMNOPQRSTUVWXYZ

private static final byte[] COMPLEMENT_TABLE_BYTES 
  = COMPLEMENT_TABLE.getBytes( StandardCharsets.US_ASCII );

然后,您可以通过简单的表查找找到补语的基础。

public static byte[] complement( byte[] sequence ) {
    int length = sequence.length;
    byte[] result = new byte[ length ];

    for ( int i = 0; i < length; ++i ) {
        result[i] = COMPLEMENT_TABLE_BYTES[ sequence[i] ];
    }

    return result;
}

如果为了方便使用小序列,您可以提供一个接受并返回String的方法。

public static String complement( String sequence ) {
    byte[] complementBytes = complement( 
      sequence.getBytes( StandardCharsets.US_ASCII ));
    return new String( complementBytes, StandardCharsets.US_ASCII );
}

可以在同一循环中计算反向补码。

public static byte[] reverseComplement( byte[] sequence ) {
    int length = sequence.length;
    byte[] result = new byte[ length ];

    for ( int i = 0; i < length; ++i ) {
        result[ (length - i) - 1] = COMPLEMENT_TABLE_BYTES[ sequence[i] ];
    }

    return result;
}

public static String reverseComplement( String sequence ) {
    byte[] complementBytes = reverseComplement( 
      sequence.getBytes( StandardCharsets.US_ASCII ));
    return new String( complementBytes, StandardCharsets.US_ASCII );
}

使用您的示例序列:

public static void main(String[] args) {
    String sequence = "ACGTA";

    String complementSequence = complement( sequence );
    System.out.println( String.format( 
       "complement(%s) = %s", sequence, complementSequence ));

    String reverseComplementSequence = reverseComplement( sequence );
    System.out.println( String.format( 
      "reverseComplement(%s) = %s", sequence, reverseComplementSequence ));
}

我们得到了这个输出:

complement(ACGTA) = TGCAT
reverseComplement(ACGTA) = TACGT