![]() |
1
11
我有点惊讶 this thread 发布了多少错误答案。为了其他人的利益,他们提出了一个类似于OP发布的解决方案,下面的代码 看 对的:
但是,代码偶尔会抛出异常,但并不总是如此。这就是调试的乐趣所在:)如果您运行足够多次,或者在一个循环中执行排序过程50次左右,您将得到一个错误声明:
换句话说,快速排序比较了一些数字
但即使这样也不行,因为有时.NET会将3个数字相互比较,结果不一致,例如A>B、B>C和C>A(糟糕!)。无论您使用的是guid、gethashcode或任何其他随机生成的输入,上面所示的解决方案仍然是错误的。 尽管如此,Fisher Yates是排列的标准方式,因此首先没有真正的理由使用iComparer。Fisher-Yates是O(n),而使用iComparer的任何实现在时间复杂度为O(n Log n)的场景之后都使用QuickSort。没有充分的理由不使用众所周知的、高效的、标准的算法来解决这类问题。 但是,如果您确实坚持使用IComparer和RAND,那么应用随机数据 之前 你排序。这需要将数据投影到另一个对象上,这样就不会丢失随机数据:
或是和你的坏自己在一起:
|
![]() |
2
3
我在别处得到的一个建议是创建一个单独的IArranger接口,该接口描述了 安排 收藏。当IComparer/IComparable不能工作时,这可以工作,因为它对整个集合而不是单个项进行操作。它可能看起来像这样:
然后我可以实现
或
或
最后一步,我通过扩展方法向任何IEnumerable添加对此的支持。然后您仍然可以得到简单的运行时算法交换,您可以更好地实现无序播放算法,并且使用它的代码感觉很自然:
|
![]() |
3
1
排序次序 要求 在某个点(对于t的相等实例)返回零,使其 数学上的 无法创建一个通用的IComparer来模拟fisher-yates的随机播放。总会有偏见的。对于真正的随机播放,您永远不希望强制它返回任何特定的值。 |
![]() |
4
0
如何基于一个预先分配了随机值的隐藏字段进行排序? |
![]() |
5
0
要跟进James Curran的想法:让iComparer将“排序”值作为列表维护;如果出现新值,请将其随机插入列表;按列表索引比较。通过将列表保持为平衡树或其他方式进行优化。这样一个IComparer的每个实例都将保持一致的随机排序顺序,因此您可以选择让您的随机排序始终保持相同的随机排序,或者每次都是不同的随机排序。如果您喜欢以这种方式读取“随机的”,微小的修改甚至允许等量元素被“排序”到不同的排序位置。 |
![]() |
6
0
一项有趣的努力。很可能是滥用/滥用公司。 您试图通过使用一种不是为此目的而构建的机制来进行随机加权排序。 为什么不实现自己的排序例程和比较器呢?我觉得即使那样也不够。 |
![]() |
7
0
不要这样做。 到目前为止提出的所有算法都会在输出中引入某种偏差(有些偏大)。 @公主和@luke建议在数据旁边存储一个随机数。然而,由于这些随机数中的任意两个可能具有与另一个相同的值,因此这两个项目之间的排序顺序将具有确定性偏差。 最坏的情况是,如果排序例程是“稳定的”(即,被认为相等的对象总是以输入的相同顺序输出)。array.sort并不稳定(它在内部使用quicksort),但当两个项具有相同的值时,仍然存在偏差,这取决于它们在输入中的位置(特别是它们相对于quicksort的轴的位置)。 随着这个随机数的键空间的增加,碰撞的概率会降低(具有很好的随机性来源),但请记住,随着正在排序的值的数目增加,生日悖论规定,其中至少一对碰撞的可能性会很快增加。 对于整数键,该键有2^32个唯一值,即使假设随机值分布完全均匀,有75000行,也有50%的概率会发生冲突。 Wikipedia . 您提出的加密散列方法可能具有足够大的密钥空间(160)位,可以忽略碰撞的可能性,但是您的算法在实际执行比较之前将所有的随机性分解回一个整数,这会抵消较大密钥空间的好处。 最好的方法是将一个不同的“sortorder”值与每个数据项相关联,使用一个经过验证的算法对这些值进行无序处理,然后按该值对结果进行排序。 如果您使用array.sort,则会有一个重载接受一个“keys”数组和一个“values”数组。键数组是正常排序的,但只要移动键数组中的值,值数组中的相应条目也会移动。 类似:
|
![]() |
Emopusta · 从后端到前端的图像路径不工作 2 年前 |
![]() |
Asdrubal Hernandez · Linq查询特定数组索引出错 2 年前 |
![]() |
Niyazi Babayev · 如何在表达式中动态应用表达式? 2 年前 |
|
Dansih · .Net核心自定义身份验证方案 2 年前 |
![]() |
lolorekkk · 面板插入。NET WinForm 2 年前 |