2013-07-08 42 views
6

Jeśli mam listę liczb całkowitych:Uzyskiwanie liczb losowych z listy liczb całkowitych

List<int> myValues = new List<int>(new int[] { 1, 2, 3, 4, 5, 6 }); 

Jak bym dostać 3 losowe liczby całkowite z tej listy?

+7

[Co próbowałeś?] (Http://www.dotnetperls.com/random) – Sayse

+0

czy kiedykolwiek spróbować go rozwiązać? czy kiedykolwiek wyszukiwałeś w google? – giammin

+0

możliwy duplikat [Jak uzyskać losowe wartości z tablicy w języku C#] (http://stackoverflow.com/questions/14297853/how-to-get-random-values- from-array-in-c-sharp) – giammin

Odpowiedz

21

Jeden prosty sposób:

Random r = new Random(); 
IEnumerable<int> threeRandom = myValues.OrderBy(x => r.Next()).Take(3); 

Lepszym sposobem: Fisher–Yates shuffle:

public static class EnumerableExtensions 
{ 
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source) 
    { 
     return source.Shuffle(new Random()); 
    } 

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng) 
    { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (rng == null) throw new ArgumentNullException("rng"); 

     return source.ShuffleIterator(rng); 
    } 

    private static IEnumerable<T> ShuffleIterator<T>(
     this IEnumerable<T> source, Random rng) 
    { 
     List<T> buffer = source.ToList(); 
     for (int i = 0; i < buffer.Count; i++) 
     { 
      int j = rng.Next(i, buffer.Count); 
      yield return buffer[j]; 

      buffer[j] = buffer[i]; 
     } 
    } 
} 

jak go używać:

IEnumerable<int> threeRandom = myValues.Shuffle().Take(3); 
0

Istnieją sposoby to robić! Proste google może pobrać setki odpowiedzi. Możesz to jednak zrobić!

myList.OrderBy(x => rnd.Next()).Take(3) 
0

Użyj poniższego kodu, aby uzyskać numer:

int k = 3; // items to select 
var items = new List<int>(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }); 
var selected = new List<int>(); 
var neededItem = k; 
var availableItem = items.Count; 
var rand = new Random(); 
while (selected.Count < k) { 
    if(rand.NextDouble() < neededItem/availableItem) { 
     selected.Add(items[availableItem-1]) 
     neededItem--; 
    } 
    availableItem--; 
} 
+1

To może wybrać ten sam produkt więcej niż jeden raz. Ponadto, nie ma potrzeby, aby uzyskać losowe podwójne i manipulować nim, po prostu użyj 'Next', aby uzyskać losowe int pomiędzy dwoma liczbami. – Servy

4

Najprostszym sposobem byłoby coś takiego:

var r = new Random(); 
var myValues = new int[] { 1, 2, 3, 4, 5, 6 }; // Will work with array or list 
var randomValues = Enumerable.Range(0, 3) 
    .Select(e => myValues[r.Next(myValues.Length)]); 

Ale lepsza metoda, jeśli chcesz tam zapewnić nie są duplikaty to używanie algorytmu przetasowania, takiego jak Fisher-Yates algorithm, a następnie wykonanie 3 pierwszych elementów:

public static T[] Shuffle<T>(IEnumerable<T> items) 
{ 
    var result = items.ToArray(); 
    var r = new Random(); 
    for (int i = items.Length; i > 1; i--) 
    { 
     int j = r.Next(i); 
     var t = result[j]; 
     result[j] = result[i - 1]; 
     result[i - 1] = t; 
    } 

    return result; 
} 

var myValues = new int[] { 1, 2, 3, 4, 5, 6 }; // Will work with any enumerable 
var randomValues = myValues.Shuffle().Take(3); 
+0

Ale ponieważ permutacje są generowane losowo, będą się powtarzać. Co jeśli chcę uzyskać wszystkie permutacje dla numeru n-cyfrowego i zapisać go gdzieś. ? – Avan

1

Łącząc other answer z this answer może prowadzić do następujących:

var rand = new Random(); 
var numbers = Enumerable.Range(1, 6).OrderBy(i => rand.Next()).ToList(); 

W tym przypadku 1 jest wartość początkowa (włącznie) i 6 jest liczbą całkowitych generowania.

0

lub to:

myList.OrderBy(x => Guid.newGuid()).Take(3) 
0
int[] x = {1,2,3,4}; 

string result = Convert.ToString(x[(new Random()).Next(4)]); 
Powiązane problemy