如何洗牌使得两个相同的元素不在一起?

How to shuffle such that two same elements are not together?

我有一个包含多个元素的字符串,有些相同,有些不同。我希望我的代码检查我的字符串中的每 2 个后续元素,如果它们相等,它应该调用一个函数 ShuffleString,其中输入变量 (randomize) 是字符串本身,它将重新- 将字符串洗牌到新位置。然后,脚本应再次检查字符串中每 2 个后续元素,直到没有两个相同的元素彼此相邻出现。


我做了以下事情:
我的函数文件 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 function to get the elements in numeric form for easier processing. Apply diff on it to check if consecutive elements are same. If there is any occurrence of same consecutive elements, the output of diff will give at least one zero which when applied with negated all will return true 的第三个输出参数继续循环,反之亦然。最后,使用循环后得到的字符串的混洗 indices/numeric 表示来索引 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. Your version of function works but it keeps changing the size of the arrays MyString and randomize and hence adversely affects the performance and memory usage。这是一个更简单的方法:

function MyString = ShuffleString(MyString)
MyString = MyString(randperm(numel(MyString)));
end