Перемешать массив си шарп

Как перемешать (случайно переставить) элементы в массиве?

Есть данные, записанные в массив или генерируемые на лету. Как можно получить их случайную перестановку в массиве или другом контейнере? Например: как можно получить случайную перестановку чисел от 1 до n в массиве/списке?

3 ответа 3

Если у вас уже есть набор данных (массив или List ), скорее всего вам нужно перемешивание его «на месте». Для этого подойдёт алгоритм из 3.4.2P из TAOCP, известный также как Fisher–Yates shuffle.

Пусть ваши данные находятся в массиве T[] data . Пусть random — экземпляр типа Random *. Тогда для перемешивания подходит следующий код:

for (int i = data.Length - 1; i >= 1; i--) < int j = random.Next(i + 1); // обменять значения data[j] и data[i] var temp = data[j]; data[j] = data[i]; data[i] = temp; >

Код очевидным образом адаптируется для случая List .

Для случая, когда вам нужна не перетасовка на месте, а заполнение данными из другого источника, или данные генерируются на ходу (например, вы хотите получить перестановку чисел 1. n), можно воспользоваться немного модифицированным алгоритмом.

Если количество данных известно заранее (пусть это будет n ), делаем так:

data = new T[n]; for (int i = 0; i

Здесь generate(i) — выражение, которое даёт следующий, i -ый член исходной последовательности. Например, если данные поступают из массива source , то generate(i) — это просто source[i] . Если вы перемешиваете числа от 1 до n , это просто i + 1 , и т. д.

Для случая, когда количество элементов не известно заранее (например, из произвольного IEnumerable ), подойдёт следующая модификация. Наш целевой контейнер должен быть List , чтобы его можно было динамически увеличивать.

data = new List(); foreach (var s in source) < int j = random.Next(data.Length + 1); if (j == data.Count) < data.Add(s); >else < data.Add(data[j]); data[j] = s; >> 

Код основан на цитированной статье из Википедии.

*Если вы пользуетесь .NET Framework (но не .NET Core), не стоит создавать новый экземпляр Random каждый раз при выполнении этого алгоритма: это даёт большие шансы, что два раза подряд сгенерированная перестановка будет фактически одинаковой. Если ваша программа однопоточная, лучше всего создать единственный статический экземпляр Random в начале программы, и использовать его.

Для .NET Core этой проблемы нет, создавайте экземпляры Random , где вам удобнее.

Источник

Shuffle an Array in C#

Shuffle an Array in C#

  1. Shuffle an Array With the Random Class in C#
  2. Shuffle an Array With the RNGCryptoServiceProvider Class in C#

This tutorial will discuss the methods to shuffle an array in C#.

Shuffle an Array With the Random Class in C#

The Random class generates random numbers in C#. The Random.Next() method generates a random integer value. We can use the Random.Next() method with LINQ to shuffle an array in C#.

using System; using System.Linq; using System.Security.Cryptography;  namespace randomize_array   class Program    static void Main(string[] args)    int[] arr = < 1, 2, 3, 4, 5 >;  Random random = new Random();  arr = arr.OrderBy(x => random.Next()).ToArray();  foreach (var i in arr)    Console.WriteLine(i);  >  >  > > 

In the above code, we shuffled the array of integers arr with the Random.Next() method and LINQ in C#. We first generated a random index with the Random.Next() method and placed each element at a random index with the OrderBy() method. We then converted the resultant data structure to an array with the ToArray() method.

Shuffle an Array With the RNGCryptoServiceProvider Class in C#

The RNGCryptoServiceProvider class in C# generates random numbers. This method is more reliable than the previous approach because the RNGCryptoServiceProvider class is more random than the Random class. The RNGCryptoServiceProvider class is mainly used for encryption, so it is more secure than the Random class. The GetBytes() method of the RNGCryptoServiceProvider class is used to fill an array of bytes with a sequence of random values. We can use the Convert.ToInt32() method to convert this random byte value into an integer. We can then use this random integer as an index for each element. The following code example shows us how we can shuffle an array with the RNGCryptoServiceProvider class in C#.

using System; using System.Linq; using System.Security.Cryptography;  namespace randomize_array   class Program    static int Next(RNGCryptoServiceProvider random)    byte[] randomInt = new byte[4];  random.GetBytes(randomInt);  return Convert.ToInt32(randomInt[0]);  >  static void Main(string[] args)    int[] arr = < 1, 2, 3, 4, 5 >;  RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();  arr = arr.OrderBy(x => Next(random)).ToArray();  foreach (var i in arr)    Console.WriteLine(i);  >  >  > > 

The logic followed in this example is the same as the previous approach. The difference is that here we are using the RNGCryptoServiceProvider class to generate a random index for our array. We defined the method Next() that generates a random integer index using the RNGCryptoServiceProvider class.

Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.

Related Article — Csharp Array

Источник

PowerCodX Blog

Здравствуйте дорогие программисты. В этой статье вы узнаете как перемешать массив или как получить массив неповторяющихся чисел.

Введение: Дело было вечером. Писал я маленькую программку, чисто для себя, чтобы попрактиковаться и получить новые навыки. Так как я программист на любительском уровне, знания в области программирования очень приветствуется. Так вот, писал я код и на какой-то момент мне мне было необходимо перемешать массив с разными числами так чтобы они были не повторялись. В Google я нашел ответ на свой вопрос.

Итак, чтобы перемешать массив достаточно писать 3-х строчный код:

var array = new[] < 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 >; var random = new Random(DateTime.Now.Millisecond); array = array.OrderBy(x => random.Next()).ToArray();

Действительно код заработал, но я хотел узнать как алгоритм работает. Я попытаюсь вам объяснить как он работает.

В первой строке вам должно быть все понятно, здесь инициализируется целочисленный массив с числами от 1 до 10.

var random = new Random(DateTime.Now.Millisecond);

Во второй строке инициализируется генератор псевдослучайных чисел, т.е. генератор который выдает случайные числа. А почему мы передали Random’у в качестве seed время в милисекундах (DateTime.Now.Millisecond)? Как я понял именно привязка к времени дает нам случайные неповторяющиеся числа.

array = array.OrderBy(x => random.Next()).ToArray();

Вот здесь самый смак :). Именно здесь я не понимал как происходит перемешивание чисел, но в конце-концов добился результатов и понял(не уверен если правильно) как происходит перемешивание массива. Кто не знает это LINQ запрос. Объяснить что это такое я не буду, так как сделать за меня может Wikipedia.
Как работает этот код? Если длина моего массива равна 10, то компилятор генерирует 10 случайных неповторяющихся чисел, помещает в временный массив, после чего массив array сортируется по возрастанию случайных чисел помещенных в временном массиве.

Пример:
До перемешивания:

Index Массив array Временный Массив
0 1 256
1 2 44
2 3 32
3 4 544
4 5 1072
5 6 14
6 7 15
7 8 21
8 9 286
9 10 428

После перемешивания:

Index Массив array Временный Массив
0 6 14
1 7 15
2 8 21
3 3 32
4 2 44
5 1 256
6 9 286
7 10 428
8 4 544
9 5 1072

Ну вот и все. Если заметили грамматические ошибки или работоспособность кода нарушена пишите в комментариях или на почту: powercodx@mail.ru

Источник

shuffle (rearrange randomly) a List [duplicate]

Obviously if you want real randomness instead of pseudo-random number generator you could use RNGCryptoServiceProvider instead of Random.

@chillitom, no this doesn’t have the problem in that article. In Eric’s article, the randomness is poorly seeded, and also the comparison is breaking the total ordering requirement of comparison methods. In Darin’s example here, each item is assigned a random number once, and then ordered according to it. I think kprobst’s solution is still better (well-known efficient shuffling algorithm), but Darin’s is correct too.

This is an extension method that will shuffle a List :

 public static void Shuffle(this IList list) < int n = list.Count; Random rnd = new Random(); while (n >1) < int k = (rnd.Next(0, n) % n); n--; T value = list[k]; list[k] = list[n]; list[n] = value; >> 

+1 I’ve not tested this in my code (i.e. not sure if it works), but I like it so far! Does every element get shuffled, or is that not necessary?

You can just say int k = rnd.Next(0, n) . The % is unnecessary since the dividend is always less than n .

There is a problem with this implementation! Initializing a new Random on each call will yield predictable shuffling results. Instead, place private static readonly Random rnd = new Random(); into the static class this method sits in. Finally, it would have been nice if you had given your source for this answer credit, because then the flaw in your own post might have been discovered sooner before people went off and used it without any hint it needed fixing.

Источник

Перемешать случайным образом массив целых чисел

Здравствуйте!
Подскажите, пожалуйста, как в C# перемешать случайным образом массив целых чисел.
Аналог random.shuffle(lst) в Python.
Спасибо!

Массив целых чисел из 10 элементов заполнить случайным образом. Упорядочить массив по убыванию. Найти сумму квадратов
Массив целых чисел из 10 элементов заполнить случайным образом. Упорядочить массив по убыванию.

Дан массив целых чисел (n=25), заполненный случайным образом числами из промежутка [-50,50]
Помогите пожалуйста написать программу на C#. Спасибо заранее) Дан массив целых чисел (n=25).

Массив 10х10 заполнить 0 и1 случайным образом но в соотношении 3:1
Добрый вечер! подскажите, пожалуйста, как заполнить матрицу 10х10 0 и1 случайным образом но в.

Заполнить массив случайным образом: вещественными значениями
Помогите с задачкой (2) 2.Заполнить массив из пятнадцати элементов случайным образом.

Это я нашел. А встроенной функции перемешивания нету?
Вот моя реализация:

1 2 3 4 5 6 7 8 9 10 11 12
public static void Shuffle(this int[] array) { if (array.Length  1) return; var random = new Random(); for (var i = 0; i  array.Length; i++) { var key = array[i]; var rnd = random.Next(i, array.Length); array[i] = array[rnd]; array[rnd] = key; } }

ЦитатаСообщение от NJohn Посмотреть сообщение

ЦитатаСообщение от Diman777 Посмотреть сообщение

Эксперт .NET

var r = new Random(); for (int i = arr.Length - 1; i > 0; i--) { int j = r.Next(i); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; }

Эксперт .NET

ЦитатаСообщение от NJohn Посмотреть сообщение

Ага, оно
Можно, конечно, придраться к тому, что последний элемент сам с собой свопнется, но это чепуха.

kolorotur, спасибо за замечание!
Действительно, так оно и есть.
Поставил условие i < array.Length-1

ЦитатаСообщение от kolorotur Посмотреть сообщение

на самом деле, это не всегда хорошо. теряется солидная доля перестановок, я насчитал (n — 1)! перестановок вместо n! . для малых n — это критично, например 4! = 24 вместо 5! = 120 для n = 5. благо, исправить несложно — заменив 4-ю строку

Эксперт .NET

ЦитатаСообщение от rattrapper Посмотреть сообщение

Почему же не хорошо, если стоит задача — перемешать?

ЦитатаСообщение от rattrapper Посмотреть сообщение

Тут важно понимать: в чем цель алгоритма.
Если цель в генерации как можно большего количества возможных комбинаций, то да — здесь не поспоришь.
Если же цель состоит в перемешивании массива и надо допустить возможность того, что какие-то из элементов могут остаться на своих местах, то нужно определить предел этому количеству. 1? 2? n/2? n? Последний вариант — это отсутствие перемешивания, т.к. конечная пермутация является идентичностью.
Потому если цель состоит в перемешивании, то лучше смириться с потерей некоторого количества пермутаций в обмен на гарантию того, что в итоге не получим идентичность.
Ну или значительно усложнять алгоритм для учета количества элементов, которым можно оставаться на местах.

Вы когда колоду карт тасуете, вам что важнее: какое количество уникальных раскладов вы можете теоретически получить или то, что у вас колода после перетасовки не будет такой же, как до?

ЦитатаСообщение от rattrapper Посмотреть сообщение

Для малых n как раз более критична гарантия перестановки, т.к. если у вас множество < 1, 2 >, то при выбранном вами подходе мы либо имеем перестановку, либо идентичность: 50/50.
Если нужно перемешивание, то меня расклад фифти-фифти ну никак не устраивает

ЦитатаСообщение от rattrapper Посмотреть сообщение

Источник

Читайте также:  Массив среднее арифметическое php
Оцените статью