首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将整数数组随机化

将整数数组随机化
EN

Stack Overflow用户
提问于 2013-05-10 14:24:54
回答 5查看 2.2K关注 0票数 1

你能帮我找到一个随机化数组的方法吗?例如:

代码语言:javascript
复制
int[] arrayInt = { 1, 2, 3, 4, 5, 6, 7 };

在随机化之后,结果应该存储在另一个数组中。

当你再次随机化时,应该将它与存储在第二个数组中的值进行比较,如果该值存在,程序必须再次随机化。

EN

回答 5

Stack Overflow用户

发布于 2013-05-10 15:31:54

下面是一种使用Enumerable.OrderBy对带有random变量的输入数组进行排序的方法。生成新序列后,将使用SequenceEqual将其与输入数组进行比较

代码语言:javascript
复制
public static T[] UniqueRandomArray<T>(T[] input, Random rnd)
{
    if (input.Length <= 1) throw new ArgumentException("Input array must have at least two elements, otherwise the output would be the same.", "input");
    IEnumerable<T> rndSeq;
    while (input.SequenceEqual(rndSeq = input.OrderBy(x => rnd.Next())));
    return rndSeq.ToArray();
}

这个示例代码生成了10个新的数组,它们被添加到一个列表中。确保新的数组与之前的数组不同:

代码语言:javascript
复制
Random rnd = new Random();
List<int[]> randomArrays = new List<int[]>();
int[] arrayInt1 = { 1, 2, 3, 4, 5, 6, 7 };
randomArrays.Add(arrayInt1);

for (int i = 0; i < 10; i++)
{
    int[] lastArray = randomArrays[randomArrays.Count - 1];
    int[] randomArray = UniqueRandomArray(lastArray, rnd);
    randomArrays.Add(randomArray);
}
票数 7
EN

Stack Overflow用户

发布于 2013-05-10 15:32:04

使用linq

代码语言:javascript
复制
        Random rand = new Random();
        int[] arrayInt =
            new[] {1, 2, 3, 4, 5, 6, 7}.Select(x => new {x, r = rand.Next()})
                                       .OrderBy(x => x.r)
                                       .Select(x => x.x)
                                       .ToArray();

你可以像这样随机化任何类型

代码语言:javascript
复制
public static class RandomExt
{
    public static T[] RandomizeOrder<T>(this T[] array)
    {
        var rand = new Random();
        return array.Select(x => new {x, r = rand.Next()})
                                       .OrderBy(x => x.r)
                                       .Select(x => x.x)
                                       .ToArray();
    }
}

int[] arrayInt = new[] {1, 2, 3, 4, 5, 6, 7}.RandomizeOrder();
票数 1
EN

Stack Overflow用户

发布于 2013-05-10 16:08:42

你问题的第一部分是关于数组的混洗。Fisher-Yates shuffle是一个很好的算法。

下一部分关于将结果与原始结果进行比较的部分有点模糊。我假设你想要创建一个随机的混洗,保证所有的元素都被混洗到一个新的位置。例如。

  • 0,1,2 => 1,2,0可以,但
  • 0,1,2 => 2,1,0不可以,因为1留在原地

为此,我已经创建了一些扩展(请注意,这是一个元素类型为T的通用解决方案):

代码语言:javascript
复制
static class EnumerableExtensions {

  static Random random = new Random();

  public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source) {
    var list = source.ToList();
    for (var k = 0; k < list.Count; k += 1) {
      var j = random.Next(k, list.Count);
      Swap(list, k, j);
    }
    return list;
  }

  public static IEnumerable<T> RandomizeUniquely<T>(this IEnumerable<T> source) {
    while (true) {
      var randomized = source.Randomize();
      var isNotUnique = source
        .Zip(randomized, (a, b) => Equals(a, b))
        .Any(equal => equal);
      if (!isNotUnique)
        return randomized;
    }
  }

  static void Swap<T>(IList<T> list, Int32 i, Int32 j) {
    var temp = list[i];
    list[i] = list[j];
    list[j] = temp;
  }

}

Randomize方法实现了费舍尔-耶茨混洗。RandomizeUniquely使用此方法并尝试创建一个满足上述条件的混洗。该方法只是尝试,直到找到令人满意的混洗。请注意,此算法可能不会终止。例如,如果源只有一个元素,则无法找到唯一的混洗。此外,如果源包含重复项,则解决方案可能不存在。

要使用该方法,只需像这样调用它:

代码语言:javascript
复制
var randomized = Enumerable.Range(1, 7).RandomizeUniquely();

可以通过验证参数和决定如何处理上述非终止问题来改进代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16476359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档