【发布时间】:2010-11-07 22:17:28
【问题描述】:
随机化数组中的项目并删除随机项目以达到所需的数组长度的最佳方法是什么?
假设我有一个包含 100 个项目的数组。
首先,我想随机化它。
然后,我有 3% 的系数:10%、30%、60%。
我想从原始数组中删除项目,所以我得到的新数组将是原始大小的 60%(60 个项目),然后是 30%,然后是 10%。
【问题讨论】:
标签: c#
随机化数组中的项目并删除随机项目以达到所需的数组长度的最佳方法是什么?
假设我有一个包含 100 个项目的数组。
首先,我想随机化它。
然后,我有 3% 的系数:10%、30%、60%。
我想从原始数组中删除项目,所以我得到的新数组将是原始大小的 60%(60 个项目),然后是 30%,然后是 10%。
【问题讨论】:
标签: c#
随机化数组的最佳方法是使用Fisher-Yates-Durstenfeld shuffle。您可以就地执行此操作(即,打乱现有数组)或创建一个包含随机顺序项目的新集合。
我可能会这样做,creating a new shuffled collection 而不是改变原始数组,然后使用Skip 和Take 来获得洗牌数组所需的子序列。 (如果您愿意,可以很容易地将此代码更改为 perform an in-place shuffle。)
// uses Shuffle extension from https://stackoverflow.com/a/1653204/55847
var temp = original.Shuffle().ToArray();
var sixty = temp.Take((int)(temp.Length * 0.6)).ToArray();
var thirty = temp.Skip(sixty.Length).Take((int)(temp.Length * 0.3)).ToArray();
var ten = temp.Skip(sixty.Length + thirty.Length).ToArray();
【讨论】:
嗯,首先你不能从数组中删除项目。数组的大小是在创建时确定的,之后就永远不会改变。如果你想要一个更小的数组,你必须创建一个新的。
您可以使用这样的扩展来随机播放项目:
public static class IEnumerableExtensions {
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> list, Random rnd) {
List<T> items = new List<T>(list);
for (int i = 0; i < items.Count; i++) {
int pos = rnd.Next(i, items.Count);
yield return items[pos];
items[pos] = items[i];
}
}
}
我不确定你所说的系数是什么意思,但我想你想在一个数组中获得前 60%,然后在第二个数组中获得另外 30%,然后在第三个数组中获得另外 10%:
IEnumerable<int> shuffled = originalArray.Shuffle(new Random()).ToList();
int cnt60 = (int)Math.Round(originalArray.Length * 0.6);
int cnt30 = (int)Math.Round(originalArray.Length * 0.3);
int cnt10 = (int)Math.Round(originalArray.Length * 0.1);
int[] first60 = shuffled.Take(cnt60).ToArray();
int[] next30 = shuffled.Skip(cnt60).Take(cnt30).ToArray();
int[] next10 = shuffled.Skip(cnt60+cnt30).Take(cnt10).ToArray();
【讨论】: