adding for loop to prevent changing char to same char

1 vue (au cours des 30 derniers jours)
Kangkeon Jeon
Kangkeon Jeon le 13 Nov 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?

Réponses (1)

Thomas Satterly
Thomas Satterly le 13 Nov 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

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by