adding for loop to prevent changing char to same char

1 visualización (últimos 30 días)
Kangkeon Jeon
Kangkeon Jeon el 13 de Nov. de 2019
Respondida: Thomas Satterly el 13 de Nov. de 2019
text = 'CGATCCGATC--------------CGCGCCGCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC';
newLetters = 'ACTG';
n = numel(text);
percentChange = 5;
idx = 1:n;
hak = isletter(text(:));
hakk = sum(hak);
idxToChange = idx(isletter(text));
nChanges = max([ceil(hakk*percentChange/100), 1]);
changeIdx = idxToChange(randperm(numel(idxToChange), nChanges));
changeLetterIdx = randi([1, numel(newLetters)], 1, nChanges);
text(changeIdx) = newLetters(changeLetterIdx);
I have this code where 5% of letters (meaning excluding dashes) in text are changed to one of other newLetters at random positions.
However, right now some of them are "changing" into same letter so not changing really. I think I need to add a for loop to prevent changing into same letter, but where and how should I write this?

Respuestas (1)

Thomas Satterly
Thomas Satterly el 13 de Nov. de 2019
This is an interesting problem and a fun challenge. You don't need a for loop, rather, you can only allow different letters to be selected.
text = 'CGATCCGATC--------------CGCGCCGCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATCCGATC';
newLetters = 'ACTG';
n = numel(text);
percentChange = 20;
idx = 1:n;
hak = isletter(text(:));
hakk = sum(hak);
idxToChange = idx(isletter(text));
nChanges = max([ceil(hakk*percentChange/100), 1]);
changeIdx = idxToChange(randperm(numel(idxToChange), nChanges));
% Find out what the current letters are
currentLetters = text(changeIdx);
% Make a logical matrix of the letter match indecies
currentIndex = currentLetters == newLetters(:);
% Convert the logical index to the row index of possible new values
[row, ~] = find(~currentIndex);
% Here's what it looks like in matrix form, but you don't actually need
% this
matrixRows = reshape(row, size(currentIndex, 1) - 1, size(currentIndex, 2));
% Generate a random integer between 1 and numel(newLetters) - 1. One less
% than the total number of letters since we are already using one of them
rowIdx = randi([1, numel(newLetters) - 1], 1, nChanges);
% Convert the row number to index number
subIndex = sub2ind([size(currentIndex, 1) - 1, size(currentIndex, 2)], rowIdx, 1: size(currentIndex, 2));
% Get the new letter index
changeLetterIdx = row(subIndex');
% Make the new string
newText = text;
newText(changeIdx) = newLetters(changeLetterIdx);
if any(newText(changeIdx) == text(changeIdx))
disp('Something didn''t change to a new value, but this should no longer be possible!');
end

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by