Best way to randomize an array with .NET

后端 未结 17 876
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 01:55

What is the best way to randomize an array of strings with .NET? My array contains about 500 strings and I\'d like to create a new Array with the same strings b

相关标签:
17条回答
  • 2020-11-22 02:36

    Just thinking off the top of my head, you could do this:

    public string[] Randomize(string[] input)
    {
      List<string> inputList = input.ToList();
      string[] output = new string[input.Length];
      Random randomizer = new Random();
      int i = 0;
    
      while (inputList.Count > 0)
      {
        int index = r.Next(inputList.Count);
        output[i++] = inputList[index];
        inputList.RemoveAt(index);
      }
    
      return (output);
    }
    
    0 讨论(0)
  • 2020-11-22 02:37

    You're looking for a shuffling algorithm, right?

    Okay, there are two ways to do this: the clever-but-people-always-seem-to-misunderstand-it-and-get-it-wrong-so-maybe-its-not-that-clever-after-all way, and the dumb-as-rocks-but-who-cares-because-it-works way.

    Dumb way

    • Create a duplicate of your first array, but tag each string should with a random number.
    • Sort the duplicate array with respect to the random number.

    This algorithm works well, but make sure that your random number generator is unlikely to tag two strings with the same number. Because of the so-called Birthday Paradox, this happens more often than you might expect. Its time complexity is O(n log n).

    Clever way

    I'll describe this as a recursive algorithm:

    To shuffle an array of size n (indices in the range [0..n-1]):

    if n = 0
    • do nothing
    if n > 0
    • (recursive step) shuffle the first n-1 elements of the array
    • choose a random index, x, in the range [0..n-1]
    • swap the element at index n-1 with the element at index x

    The iterative equivalent is to walk an iterator through the array, swapping with random elements as you go along, but notice that you cannot swap with an element after the one that the iterator points to. This is a very common mistake, and leads to a biased shuffle.

    Time complexity is O(n).

    0 讨论(0)
  • 2020-11-22 02:37

    Generate an array of random floats or ints of the same length. Sort that array, and do corresponding swaps on your target array.

    This yields a truly independent sort.

    0 讨论(0)
  • 2020-11-22 02:38

    This algorithm is simple but not efficient, O(N2). All the "order by" algorithms are typically O(N log N). It probably doesn't make a difference below hundreds of thousands of elements but it would for large lists.

    var stringlist = ... // add your values to stringlist
    
    var r = new Random();
    
    var res = new List<string>(stringlist.Count);
    
    while (stringlist.Count >0)
    {
       var i = r.Next(stringlist.Count);
       res.Add(stringlist[i]);
       stringlist.RemoveAt(i);
    }
    

    The reason why it's O(N2) is subtle: List.RemoveAt() is a O(N) operation unless you remove in order from the end.

    0 讨论(0)
  • 2020-11-22 02:38

    You don't need complicated algorithms.

    Just one simple line:

    Random random = new Random();
    array.ToList().Sort((x, y) => random.Next(-1, 1)).ToArray();
    

    Note that we need to convert the Array to a List first, if you don't use List in the first place.

    Also, mind that this is not efficient for very large arrays! Otherwise it's clean & simple.

    0 讨论(0)
  • 2020-11-22 02:41

    You can also make an extention method out of Matt Howells. Example.

       namespace System
        {
            public static class MSSystemExtenstions
            {
                private static Random rng = new Random();
                public static void Shuffle<T>(this T[] array)
                {
                    rng = new Random();
                    int n = array.Length;
                    while (n > 1)
                    {
                        int k = rng.Next(n);
                        n--;
                        T temp = array[n];
                        array[n] = array[k];
                        array[k] = temp;
                    }
                }
            }
        }
    

    Then you can just use it like:

            string[] names = new string[] {
                    "Aaron Moline1", 
                    "Aaron Moline2", 
                    "Aaron Moline3", 
                    "Aaron Moline4", 
                    "Aaron Moline5", 
                    "Aaron Moline6", 
                    "Aaron Moline7", 
                    "Aaron Moline8", 
                    "Aaron Moline9", 
                };
            names.Shuffle<string>();
    
    0 讨论(0)
提交回复
热议问题