2014-01-29 4 views
2

Мне нужно написать функцию для замены символов строки этими буквами.Замена нескольких разных символов строки

A=U 
T=A 
G=C 
C=G 

Пример:

 Input: 'ATAGTACCGGTTA' 

Таким образом, выходной сигнал должен быть:

'UAUCAUGGCCAAU' 

можно заменить только один символ. Однако у меня нет способов сделать несколько. Я мог бы заменить несколько, если «G = C и C = G» это условие не было. я использую:

in='ATAGTACCGGTTA' 
check=in=='A' 
in(check)='U' 
ans='UTUGTUCCGGTTU' 

, если я продолжаю делать это в каком-то точке G будет заменен на С, то тогда весь C будет заменено G. Как я могу остановить это ?? Любая помощь будет оценена.

ответ

2

Простейшим способом было бы использовать промежуточное письмо. Например:

in='ATAGTACCGGTTA' 
in(in == 'A')='U' 
in(in == 'T')='A' 
in(in == 'C')='X' 
in(in == 'G')='C' 
in(in == 'X')='G' 

Таким образом, вы сохраняете символы «C» и «G».

EDIT:

Как уже упоминалось, есть несколько вещей других вещей, которые вы могли бы сделать, чтобы улучшить этот подход (хотя лично я думаю, что путь Notlikethat является надёжным). Например, если вы используете вторую переменную, вам не придется беспокоиться о сохранении «C» и «G» обособлены

in='ATAGTACCGGTTA' 
out=in; 
out(in == 'A')='U'; 
out(in == 'T')='A'; 
out(in == 'C')='G'; 
out(in == 'G')='C'; 

В качестве альтернативы, вы можете сделать ваши индексы, а затем индекс после:

in='ATAGTACCGGTTA' 
inA=in=='A'; 
inT=in=='T'; 
inC=in=='C'; 
inG=in=='G'; 
in(inA)='U'; 
in(inT)='A'; 
in(inC)='G'; 
in(inG)='C'; 

Наконец, мой личный фаворит для чистого идиотизма:

out=char(in+floor((68-in).*(in<70)*7/4)*4-round(ceil((in-67)/4)*3.7)); 

(Серьезно, что последний работает)

+0

Я нашел этот самый полезный для меня в данный момент. Это то, что я узнал до сих пор на самом деле. Некоторые другие команды для меня новы! Благодаря! – user3226108

+0

Вы можете устранить необходимость в 'X', используя вместо него вторую выходную переменную. Также таким образом вы сохраняете свой вклад, который часто бывает полезен. Так, например, 'out (in == 'A') = 'U'' и т. Д. ... – Dan

+0

Для подхода, основанного на письме, я бы предложил сначала создать все индексы:' idxBecomeU = in == T'. Затем вы можете просто применить их по одному, что может быть даже немного проще. –

1

Я хотел бы предложить использовать containter.Map:

m=containers.Map({'A','T','G','C'},{'U','A','C','G'}) 
[email protected](input)(cell2mat(m.values(num2cell(input)))) 

Использование:

mapfkt('ATAGTACCGGTTA') 
+1

Это то, что я хотел бы предложить, кроме того, что я предпочитаю вызывать 'values', как вы бы назвали метод класса (т. Е.' M.values ​​(num2cell (input)) '). – chappjc

+0

обновил мой ответ. – Daniel

+0

Наши решения действительно хороши, если каждый элемент получает переведенное значение. Если это что-то более сложное, чем базовые пары ДНК, это может стать волосатым ... – chappjc

2

Вы можете выполнять несколько переводов символов с bsxfun.

Входы:

in = 'ATAGTACCGGTTA'; 
pat = ['A','T','G','C']; 
subst = ['U','A','C','G']; 
out0 ='UAUCAUGGCCAAU'; 

Перевести все символы одновременно:

>> ii = (1:numel(pat))*bsxfun(@eq,in,pat.'); %' instead of repmat and .* 
>> out = subst(ii) 
out = 
UAUCAUGGCCAAU 
>> isequal(out,out0) 
ans = 
    1 

Допустим, вы хотите только перевести подмножество символов, оставляя часть последовательности неповрежденными, это легко решаются с логической индексацией и несколькими дополнительными линиями:

% Leave the Gs and Cs in place 
pat = ['A','T']; 
subst = ['U','A']; 

ii = (1:numel(pat))*bsxfun(@eq,in,pat.'); %' same 
out = char(zeros(1,numel(in))); 
nz = ii>0; 
out(nz) = subst(ii(nz)); 
out(~nz) = in(~nz) 

out = 

UAUGAUCCGGAAU 

Оригинальные Gs и Cs не изменяются; A Ставка ¥ U, T Ставка ¥ A (T нет).

4

Просто для удовольствия, здесь, вероятно, абсолютный простой способ, с помощью индексирования:

key = 'UGCA'; 
[~, ~, idx] = unique(in); 
out = key(idx'); % transpose idx since unique() returns a column vector 

Я люблю индексацию: D

Edit: Как справедливо отмечалось, это очень оптимизирован для вопроса как указано. Поскольку [a, ~, idx] = unique(in); возвращается a и idx такие, что a(idx) == in, и по умолчанию a отсортирован, мы можем только предположить, что a == 'ACGT' и предварительно построить key быть соответствующий перевод показателей в a.

Если некоторые символы из известного алфавита никогда не появляются во входной строке или появляются другие неизвестные символы, то индексы не совпадают и предположение прерывается. В этом случае, мы должны вычислить соответствующий ключ в явном виде - заполнение шага, который был оптимизирован выше:

alph = 'ACGT'; 
trans = 'UGCA'; 
[key, ~, idx] = unique(in); 
[~, alphidx, keyidx] = intersect(alph, key); % find which elements of alph 
               % appear at which points in key 
key(keyidx) = trans(alphidx); % translate the elements of key that we can 
out = key(idx'); 
+1

Вы используете Octave, не так ли? :) – chappjc

+0

@chappjc Честно говоря, я задавался вопросом, почему индексирование константы сработало ... – Notlikethat

+0

Выглядит хорошо. Хороший вызов с использованием 'unique' для индексирования, но, честно говоря, мое решение также является 2 строками.;) – chappjc

0

Вот еще один метод, который должен быть достаточно эффективным, вообще говоря, и в линии мысли о вашем оригинальная попытка:

%Suppose this is your input 
myString = 'abcdeabcde'; 
fromSting = 'ace'; 
toString = 'xyz'; 

%Then it just takes this: 
[idx fromLocation] = ismember(myString,fromSting) 
myString(idx)=toString(fromLocation(idx)) 

Если вы знаете, что все буквы должны быть заменены, последняя строка может быть немного упрощена, как вам не нужно использовать idx.

Смежные вопросы