adding for loop to prevent changing char to same char

1 次查看(过去 30 天)
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?

回答(1 个)

Thomas Satterly
Thomas Satterly 2019-11-13
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

类别

Help CenterFile Exchange 中查找有关 Data Type Conversion 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by