связывание страниц с панели навигации в файле js

Если вы заранее знаете общее количество элементов для случайного выбора, вы можете сделать это, не переходя в список в первую очередь.

Следующий метод сделает это за вас:

/// Randomly selects items from a sequence.
/// The type of the items in the sequence.
/// The sequence from which to randomly select items.
/// The number of items to randomly select from the sequence.
/// The number of items in the sequence among which to randomly select.
/// The random number generator to use.
/// A sequence of randomly selected items.
/// This is an O(N) algorithm (N is the sequence length).

public static IEnumerable RandomlySelectedItems(IEnumerable sequence, int count, int sequenceLength, System.Random rng)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    if (count < 0 || count > sequenceLength)
    {
        throw new ArgumentOutOfRangeException("count", count, "count must be between 0 and sequenceLength");
    }

    if (rng == null)
    {
        throw new ArgumentNullException("rng");
    }

    int available = sequenceLength;
    int remaining = count;
    var iterator  = sequence.GetEnumerator();

    for (int current = 0; current < sequenceLength; ++current)
    {
        iterator.MoveNext();

        if (rng.NextDouble() < remaining/(double)available)
        {
            yield return iterator.Current;
            --remaining;
        }

        --available;
    }
}

(Ключевым моментом здесь является необходимость знать с самого начала количество элементов на выбор, это немного уменьшает полезность. Но если получение счета выполняется быстро и буферизует все элементы, то потребуется слишком много памяти , это полезное решение.)


Вот еще один подход, который использует выборки резервуаров

. Этот подход НЕ требуется знать общее количество элементы на выбор, но он должен буферизовать вывод. Разумеется, он также должен перечислить всю коллекцию ввода.

Поэтому это действительно полезно, если вы заранее не знаете количество элементов на выбор (или количество элементов для выбора из очень большой).

Я бы рекомендовал просто перетасовать список в соответствии с ответом Хенка, а не делать это таким образом, но я включаю его здесь ради интереса:

// n is the number of items to randomly choose.

public static List RandomlyChooseItems(IEnumerable items, int n, Random rng)
{
    var result = new List(n);
    int index = 0;

    foreach (var item in items)
    {
        if (index < n)
        {
            result.Add(item);
        }
        else
        {
            int r = rng.Next(0, index + 1);

            if (r < n)
                result[r] = item;
        }

        ++index;
    }

    return result;
}

В качестве дополнения к ответу Хенка, это каноническая реализация алгоритма Shuffle, который он упоминает. В этом случае _rng является экземпляром Random:

/// Shuffles the specified array.
/// The type of the array elements.
/// The array to shuffle.

public void Shuffle(IList array)
{
    for (int n = array.Count; n > 1;)
    {
        int k = _rng.Next(n);
        --n;
        T temp = array[n];
        array[n] = array[k];
        array[k] = temp;
    }
}

0
задан goutham goud 13 July 2018 в 06:42
поделиться