Random playlist algorithm

后端 未结 12 1525
北恋
北恋 2020-12-09 04:58

I need to create a list of numbers from a range (for example from x to y) in a random order so that every order has an equal chance.

I need this for a music player I

12条回答
  •  既然无缘
    2020-12-09 05:50

    It is pretty much impossible to do it without allocating extra memory. If you're worried about the amount of extra memory allocated, you could always pick a random subset and shuffle between those. You'll get repeats before every song is played, but with a sufficiently large subset I'll warrant few people will notice.

    const int MaxItemsToShuffle = 20;
    public static IEnumerable RandomIndexes(int count)
    {
        Random random = new Random();
    
        int indexCount = Math.Min(count, MaxItemsToShuffle);
        int[] indexes = new int[indexCount];
    
        if (count > MaxItemsToShuffle)
        {
            int cur = 0, subsetCount = MaxItemsToShuffle;
            for (int i = 0; i < count; i += 1)
            {
                if (random.NextDouble() <= ((float)subsetCount / (float)(count - i + 1)))
                {
                    indexes[cur] = i;
                    cur += 1;
                    subsetCount -= 1;
                }
            }
        }
        else
        {
            for (int i = 0; i < count; i += 1)
            {
                indexes[i] = i;
            }
        }
    
        for (int i = indexCount; i > 0; i -= 1)
        {
            int curIndex = random.Next(0, i);
            yield return indexes[curIndex];
    
            indexes[curIndex] = indexes[i - 1];
        }
    }
    

提交回复
热议问题