打乱列表(包含重复项)以避免相同的元素彼此相邻

Mat*_*ell 5 language-agnostic algorithm shuffle

我想知道是否有一种“最佳”方法来打乱包含重复项的元素列表,以便尽可能避免 array[i] == array[i+1] 的情况。

我正在研究加权广告显示(我可以调整任何给定广告商的每次旋转的显示数量),并且希望避免同一广告商连续出现两次。

Mat*_*ell 0

作为参考,我的(非常)天真的方法是这样的(实际上使用 LINQ/SQL 调用,但这是简化的):

var advertisers = getAdvertisers();
var returnList = new List();
int totalWeight = sumOfAllAdvertisersWeight();
while (totalWeight > 0)
{
    for (int i=0; i<advertisers.Count; i++)
    {
        if (advertisers[i].Weight > 0)
        {
            returnList.add(advertisers[i]);
            advertisers[i].Weight--;
            totalWeight--;
        }
    }
}
return returnList;
Run Code Online (Sandbox Code Playgroud)

这将避免重复直到最后,但是是的,之后通过 returnList 向后检查是值得的,如果有任何重复的尾部,请尝试将它们更早地放入混合中。