var r = new Random();
var orderedList = aListOfPeople.OrderBy(x => x.Age).ThenBy(x => r.Next());
按"年龄"排序然后按随机排序的更好方法是什么?
我的目标是确保如果PersonA年龄= PersonB年龄,在某些情况下PersonA会优先出现,而PersonB会在其他一些情况下优先出现。
使用SQL
中的技术var orderedList = aListOfPeople.OrderBy(x => x.Age).ThenBy(x => Guid.NewGuid());
警告:这不是一个真正的随机,只是一个懒惰的方法,请参阅问题的评论部分
最简单的答案是先洗牌,然后排序。如果使用稳定排序,那么sort 必须为等键值保留洗牌顺序。然而,即使一个不稳定的排序会扰乱你的洗牌,我也想不出任何合理的情况下它可以取消洗牌等键值。
这可能有点低效,尽管…
如果你关心碰撞,我可以假设你的年龄是以年为单位的整数年龄。在这种情况下,您可能会考虑基数排序(256个bin对任何活着的人来说都足够了),当需要将这些bin缝合在一起时,您将以随机顺序从每个bin中删除元素,然后将它们附加到列表中。
如果列表已经按年龄排序,而您只想就地洗牌,那么您只需要遍历列表,计算下面有多少元素相等,对这些元素执行就地洗牌,然后前进到下一个不匹配的元素并重复。
我想后者应该是这样的(我会用C写,因为我不懂c#):
int i = 0;
while (i < a.length) {
int j;
while (a[j] == a[i] && j < a.length) j++;
while (i + 1 < j) {
int k = random(j - i) + i;
swap(a[i], a[k]);
i++;
}
i++;
}
还没有测试过,但它应该给了一个大致的概念。