2017-10-13 69 views
1

我有一个字符串包含几个元素,一些相同和一些独特的。我希望我的代码检查我的字符串中的每个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 

它似乎只是重新洗牌字符串无限次。这有什么问题,我该如何让它工作?

+0

,因为你使用的是无限循环? '而(1)'。 –

回答

3

您正在使用无限的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。你的函数版本可以工作,但它不断改变阵列的尺寸MyStringrandomize,因此adversely affects the performance and memory usage。这里有一个简单的方法:

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

哇,太棒了!完美的作品,正是我想要的,非常感谢你! – Birks

相关问题