2010-01-07 1 views
5

Я хочу сгенерировать массив, который имеет 144 числа из 1-> 36 в случайном порядке (поэтому каждое число повторяется 4 раза). Можем ли мы использовать Enumerable.Repeat и Enumerable.Range для этого. Если да, то пожалуйста объясните мне как?Сгенерировать и повторить число в C#

ответ

10

Ну, создавая последовательность со всеми числами в легко:

var items = from x in Enumerable.Range(1, 36) 
      from y in Enumerable.Repeat(x, 4) 
      select y; 

Тогда вы можете просто использовать ToArray, чтобы получить его в массив и перемешайте его. Существует множество вопросов о перетасовке массива в C# на SO, например this one. Вы можете использовать этот код напрямую или позвонить ToArray и перетасовать массив на месте, не уступая его в конце.

+0

эй, это более читаемым, чем мое решение. +1 –

+0

и более элегантный, что мой многократный Concat;) –

+0

спасибо за комментарий, но теперь мне нужно заполнить сгенерированный массив массивом [9,16], можете ли вы предложить хороший способ для меня? –

0
int[] numbers = Enumerable.Range(0, 144).Select(i => (i % 36)+1).OrderBy(g => Guid.NewGuid()).ToArray(); 
+0

Возможно, это не важно в этом случае, но этот способ перетасовки заканчивается тем, что O (n log n), где ему только нужно быть O (п). –

0
// Generate the list (not in random order) 
var one_to_36 = Enumerable.Range(1, 36); 
var lst = one_to_36.Concat(one_to_36).Concat(one_to_36).Concat(one_to_36).ToList(); 

// Randomize the list by swapping random elements 
Random rnd = new Random(); 
for(int i = 0; i < lst.Count; i++) 
{ 
    int i1 = rnd.Next(lst.Count); 
    int i2 = rnd.Next(lst.Count); 
    int tmp = lst[i1]; 
    lst[i1] = lst[i2]; 
    lst[i2] = tmp; 
} 
+0

Обмен случайными элементами таким образом не дает хорошего случайного распределения - есть лучший способ перетасовки коллекции, как это связано с моим ответом. –

+0

Я не понимал, что ... спасибо за подсказку –

0
var seq = Enumerable.Range(0, 144);  
var all = seq.ToList(); 
var random = new Random(); 
var result = seq.Select(i => { 
var index = random.Next()%all.Count; 
var r = all[index] % 36 + 1; all.RemoveAt(index); 
return r; 
}).ToList();