Функция .replace () неправильно меняет местами символы - PullRequest
0 голосов
/ 21 марта 2019

Я пишу функцию, которая заменяет определенные символы на другие

public static String makeComplement(String dna) {
    if(dna.contains("A")|| (dna.contains("T") ||(dna.contains("G") ||(dna.contains("C") ) )) ){
        dna = dna.replace('A' , 'T');
        dna = dna.replace('T' , 'A');
        dna = dna.replace('G' , 'C');
        dna = dna.replace('C' , 'G');

        System.out.println(dna);
    }
    return dna;
}

public static void main(String[] args) {
    String ex ="GTACTCC";
    System.out.println(ex);

    makeComplement(ex);
}

он заменяет T в A и C в G, но сохраняет A & G таким же.

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Вызов String.contains и / или String.replace потенциально сканирует всю строку, поэтому ее многократный вызов может быть дорогостоящим для очень длинных строк.

Почему бы не сделать все замены за один проход:

// Copy the original DNA string to a new mutable char array
char[] dnaCopy = dna.toCharArray();

// Examine each character of array one time only and replace
// as necessary
for(int i = 0; i < dnaCopy.length; i++) {
  if(dnaCopy[i] == 'A') {
     dnaCopy[i] = 'T';
  }
  else if(dnaCopy[i] == 'T') {
     dnaCopy[i] = 'A';
  }
  else if(dnaCopy[i] == 'G') {
     dnaCopy[i] = 'C';
  }
  else if(dnaCopy[i] == 'C') {
     dnaCopy[i] = 'G';
  }
}

// Now you can do whatever you want with dnaCopy: make a new String, etc

Этот подход должен быть намного более производительным для длинных строк и потенциально может масштабироваться с использованием подхода "разделяй и властвуй" (т. Е. У вас может быть 2 потока, работающих на одной половине массива одновременно).

2 голосов
/ 21 марта 2019

Конечно, это так.

dna = dna.replace('A' , 'T'); // replaces As with Ts
dna = dna.replace('T' , 'A'); // replace Ts with As (including the As that 
                              // were replaced with Ts)
dna = dna.replace('G' , 'C'); // replaces Gs with Cs
dna = dna.replace('C' , 'G'); // replace Cs with Gs (including the Gs that 
                              // were replaced with Cs)

Если вы хотите поменять местами как с Ts и G с C, вам, вероятно, следует использовать несколько промежуточных букв:

dna = dna.replace('A' , 'X');
dna = dna.replace('T' , 'A'); // only original Ts will become As 
dna = dna.replace('X' , 'T');
dna = dna.replace('G' , 'Y');
dna = dna.replace('C' , 'G'); // only original Cs will become Gs
dna = dna.replace('Y' , 'C');

EDIT: AsМайк прокомментировал, что вы можете сделать эту замену намного эффективнее без replace метода:

StringBuilder sb = new StringBuilder (dna.length());
for (char c : dna.toCharArray()) {
    if (c == 'A')
        sb.append('T');
    else if (c == 'T')
        sb.append('A');
    else if (c == 'G')
        sb.append('C');
    else if (c == 'C')
        sb.append('G');
} 
dna = sb.toString();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...