c# - 以随机顺序调用方法列表?

标签 c#

我有 10 种方法的列表。现在我想以随机顺序调用这些方法。该序列应在运行时生成。执行此操作的最佳方法是什么?

最佳答案

每当有人询问如何在 StackOverflow 上打乱一列事物时,看到的错误和低效答案的数量总是让我感到惊讶。这里我们有几个代码示例,它们很脆弱(因为它假设键冲突是不可能的,而实际上它们只是很少见)或对于大型列表来说很慢。 (在这种情况下,问题只涉及十个元素,但如果可能的话,最好给出一个可以扩展到数千个元素的解决方案,如果这样做并不困难的话。)

这不是一个很难正确解决的问题。正确、快速的方法是创建一个 Action 数组,然后使用 Fisher-Yates Shuffle 就地随机播放该数组。

http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

有些事情不能做:

  • 不要错误地实现 Fischer-Yates 洗牌。人们看到这个微不足道的算法的错误实现比正确实现更多。特别是,确保您从正确的范围内选择随机数。从错误的范围中选择它会产生有偏差的洗牌。

  • 如果洗牌算法实际上必须不可预测,则使用 Random 以外的随机源,它只是伪随机。请记住,Random 只有 232 个可能的种子,因此可能的洗牌次数少于那么多。

  • 如果您要在短时间内进行多次随机播放,请不要每次都创建一个新的 Random 实例。保存并重新使用旧的,或者完全使用不同的随机源。 Random 根据时间选择种子;许多连续创建的 Random 将产生相同的“随机”数字序列。

  • 不要将“随机”GUID 作为您的键进行排序。 GUID 保证唯一。它们不能保证随机排序。实现吐出连续的 GUID 是完全合法的。

  • Do not use a random function as a comparator and feed that to a sorting algorithm .如果比较器不好,排序算法可以为所欲为,包括崩溃,以及产生非随机结果。作为Microsoft recently found out, it is extremely embarrassing to get a simple algorithm like this wrong.

  • 不使用随机输入作为字典的键,然后对字典进行排序。没有什么可以阻止随机源两次选择相同的 key ,因此要么使您的应用程序因重复 key 异常而崩溃,要么默默地丢失您的一种方法。

  • 不要使用算法“创建两个列表。将元素添加到第一个列表。重复将随机元素从第一个列表移动到第二个列表,从第一个列表中删除该元素”。如果列表是 O(n) 来删除一个项目,那么这是一个 O(n2) 算法。

  • 不使用算法“创建两个列表。将元素添加到第一个列表。重复将随机非空元素从第一个列表移动到第二个列表,将第一个列表中的元素设置为空” Also do not do this crazy equivalent of that algorithm.如果列表中有很多项目,那么随着您开始遇到越来越多的空值,它会变得越来越慢。

关于c# - 以随机顺序调用方法列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5519385/

相关文章:

c# - 反序列化时 C# 类中的字段初始值设定项不运行

c# - 在 web.config 文件中使用授权时被重定向回登录屏幕

c# - 如何在 RSA 实例的实例化中使用 Json Web key

c# - Microsoft.Azure.KeyVault.Core 无法使用 NETStandard20 进行恢复

c# - C#中在语句外声明using语句的目标对象

c# - NLog - 如何加密数据库中记录的堆栈跟踪

c# - 在 Asp.net 中检索对象列表

c# - 将子文件夹中的所有文件移动到另一个文件夹

c# - WPF 与 RelativeSource 和 AncestorType 的绑定(bind)

c# - 如何清除 CommandManager 注册的命令绑定(bind)?