如何改变这两个相同的元素不在一起?

时间:2017-10-13 01:04:24

标签: matlab loops shuffle

我有一个包含几个元素的字符串,有些是相同的,有些是唯一的。我希望我的代码检查我的字符串中的每两个后面的元素,如果它们相等,它应该调用一个函数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

它似乎只是无限次地重新洗牌。这有什么问题,我怎样才能让它发挥作用?

1 个答案:

答案 0 :(得分:3)

您正在使用无法中断的无限while循环,因此它会继续迭代。

这是一种更简单的方法:
使用unique函数的第三个输出参数来获取数字形式的元素,以便于处理。在其上应用diff以检查连续元素是否相同。如果出现任何相同的连续元素,diff的输出将至少给出一个零,当应用negated all时,将返回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。您的函数版本有效,但它会不断更改数组MyStringrandomize以及adversely affects the performance and memory usage的大小。这是一种更简单的方法:

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