2010-01-07 7 views
5

Ich möchte ein Array erzeugen, das 144 Zahlen von 1-> 36 in zufälliger Reihenfolge hat (also wird jede Zahl 4 mal wiederholt). Können wir Enumerable.Repeat und Enumerable.Range dazu verwenden? Wenn ja, bitte erklären Sie mir wie?Generiere und wiederhole die Nummer in C#

Antwort

10

Nun, mit allen Zahlen die Reihenfolge der Erstellung in ist einfach:

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

Dann können Sie einfach ToArray verwenden Sie es in ein Array zu bekommen und mische es. Es gibt zahlreiche Fragen zum Mischen eines Arrays in C# auf SO, z. B. this one. Sie können diesen Code entweder direkt verwenden oder ToArray aufrufen und das Array an Ort und Stelle mischen, ohne es am Ende zu verlieren.

+0

hey, das ist besser lesbar als meine Lösung. +1 –

+0

und eleganter, dass meine mehrere Concat;) –

+0

danke für den Kommentar, aber jetzt muss ich die generierte Array zu einem [9,16] -Array füllen, können Sie einen guten Weg für mich vorschlagen? –

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

Wahrscheinlich nicht wichtig in diesem Fall, aber diese Art des Mischens endet als O (n log n), wo es nur O sein muss (n). –

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

Der Austausch von zufälligen Elementen auf diese Weise ergibt keine gute zufällige Verteilung - es gibt eine bessere Möglichkeit, eine Sammlung zu mischen, wie in meiner Antwort verlinkt. –

+0

Ich habe das nicht bemerkt ... danke für den Tipp –

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();