首页 > 后端开发 > C++ > 如何使用 LINQ 随机打乱集合的子集?

如何使用 LINQ 随机打乱集合的子集?

DDD
发布: 2025-01-01 08:05:09
原创
208 人浏览过

How Can I Randomly Shuffle a Subset of a Collection Using LINQ?

使用 Fisher-Yates-Durstenfeld 在 LINQ 中随机打乱子集合

处理大型数据集时,从给定集合中获取特定大小的随机打乱集合变为至关重要的。这通常出现在涉及随机选择或抽样的场景中。让我们探索一个基于 LINQ 的最佳解决方案来解决此问题。

Fisher-Yates-Durstenfeld 洗牌算法提供了一种高效可靠的随机洗牌方法。在这种情况下,目标是从“N”个元素的集合中生成大小为“n”的随机子集,其中“n”小于或等于“N”。

实现此算法使用 LINQ,我们可以利用封装 shuffle 操作的扩展方法。以下代码片段提供了一个全面的实现:

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (rng == null) throw new ArgumentNullException(nameof(rng));

    return source.ShuffleIterator(rng);
}

private static IEnumerable<T> ShuffleIterator<T>(
    this IEnumerable<T> source, Random rng)
{
    var buffer = source.ToList();
    for (int i = 0; i < buffer.Count; i++)
    {
        int j = rng.Next(i, buffer.Count);
        yield return buffer[j];

        buffer[j] = buffer[i];
    }
}
登录后复制

在此实现中,Shuffle 扩展方法接受输入序列源和名为 rng 的 Random 实例。它根据输入序列创建一个缓冲区列表并迭代它,随机选择元素。所选元素作为迭代器返回,保留随机排序。

要使用此扩展方法,只需将 .Shuffle() 附加到输入序列,然后附加 .Take(n),其中 n 表示所需的大小已打乱顺序的子集合。例如:

var randomItems = yourCollection.Shuffle().Take(n);
登录后复制

这种基于 Linq 的方法提供了一种简洁高效的解决方案,用于随机洗牌并从给定集合中获取任意大小的子集合。它特别适合需要真正随机化的场景。

以上是如何使用 LINQ 随机打乱集合的子集?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板