如何洗牌,使两个相同的元素不在一起?
我有一个字符串包含几个元素,一些相同和一些独特的。我希望我的代码检查我的字符串中的每个2个元素,如果它们相同,它应该调用一个函数ShuffleString
,其中输入变量(randomize
)是字符串本身,它将在新位置重新洗牌字符串。然后,脚本应该再次检查字符串中的每个后续元素,直到没有两个相同的元素彼此相邻。如何洗牌,使两个相同的元素不在一起?
我也做了以下内容:
我的函数文件ShuffleString
工作正常。如前所述,输入变量randomize
包含与MyString
相同的元素,但排列顺序不同,因为这是脚本早期不相关事项所需的。
function [MyString] = ShuffleString(randomize)
MyString = [];
while length(randomize) > 0
S = randi(length(randomize), 1);
MyString = [MyString, randomize(S)];
randomize(S) = [];
end
该脚本不能按预期工作。现在它看起来像这样:
MyString = ["Cat" "Dog" "Mouse" "Mouse" "Dog" "Hamster" "Zebra" "Obama"...
"Dog" "Fish" "Salmon" "Turkey"];
randomize = MyString;
while(1)
for Z = 1:length(MyString)
if Z < length(MyString)
Q = Z+1;
end
if isequal(MyString{Z},MyString{Q})
[MyString]=ShuffleString(randomize)
continue;
end
end
end
它似乎只是重新洗牌字符串无限次。这有什么问题,我该如何让它工作?
您正在使用无限的while
循环,无法中断,因此它会一直迭代。
这是一个更简单的方法:
使用unique
函数的第三个输出参数来获取数字形式的元素,以便于处理。在其上应用diff
以检查连续元素是否相同。如果出现任何相同的连续元素,则diff
的输出将给出至少一个零,当与negatedall
一起应用时,将返回true
以继续该循环,反之亦然。最后,使用循环后获得的字符串的混编索引/数字表示来索引第一个输出参数unique
(之前计算的值)。因此,该脚本将是:
MyString = ["Cat" "Dog" "Mouse" "Mouse" "Dog" "Hamster" "Zebra" "Obama"...
"Dog" "Fish" "Salmon" "Turkey"]; %Given string array
[a,~,c] = unique(MyString);%finding unique elements and their indices
while ~all(diff(c)) %looping until there are no same strings together
c = ShuffleString(c); %shuffling the unique indices
end
MyString = a(c); %using the shuffled indices to get the required string array
对于功能ShuffleString
,一个更好的办法是使用randperm
。你的函数版本可以工作,但它不断改变阵列的尺寸MyString
和randomize
,因此adversely affects the performance and memory usage。这里有一个简单的方法:
function MyString = ShuffleString(MyString)
MyString = MyString(randperm(numel(MyString)));
end
哇,太棒了!完美的作品,正是我想要的,非常感谢你! – Birks
,因为你使用的是无限循环? '而(1)'。 –