all combinations of k elements out of n

Это выглядит очень небезопасным (очень мало синхронизации); как насчет чего-то как:

class SizeQueue<T>
{
    private readonly Queue<T> queue = new Queue<T>();
    private readonly int maxSize;
    public SizeQueue(int maxSize) { this.maxSize = maxSize; }

    public void Enqueue(T item)
    {
        lock (queue)
        {
            while (queue.Count >= maxSize)
            {
                Monitor.Wait(queue);
            }
            queue.Enqueue(item);
            if (queue.Count == 1)
            {
                // wake up any blocked dequeue
                Monitor.PulseAll(queue);
            }
        }
    }
    public T Dequeue()
    {
        lock (queue)
        {
            while (queue.Count == 0)
            {
                Monitor.Wait(queue);
            }
            T item = queue.Dequeue();
            if (queue.Count == maxSize - 1)
            {
                // wake up any blocked enqueue
                Monitor.PulseAll(queue);
            }
            return item;
        }
    }
}

(редактирование)

В действительности, Вы хотели бы способ закрыть очередь так, чтобы читатели начали выходить чисто - возможно, что-то как флаг bool - если установлено, пустая очередь просто возвращается (вместо того, чтобы блокироваться):

bool closing;
public void Close()
{
    lock(queue)
    {
        closing = true;
        Monitor.PulseAll(queue);
    }
}
public bool TryDequeue(out T value)
{
    lock (queue)
    {
        while (queue.Count == 0)
        {
            if (closing)
            {
                value = default(T);
                return false;
            }
            Monitor.Wait(queue);
        }
        value = queue.Dequeue();
        if (queue.Count == maxSize - 1)
        {
            // wake up any blocked enqueue
            Monitor.PulseAll(queue);
        }
        return true;
    }
}
23
задан Tamas 28 February 2015 в 22:28
поделиться

1 ответ

Вы можете использовать std :: next_permutation , но это n! а не п выбрать к. Вы можете отфильтровать их после того, как вы их создали. Но это решение O (n!), Не совсем идеальное. Вот решение проб и ошибок:

int factorial(int value)
{
    int result = 1;

    for(int i = 1; i <= value; i++)
    {
        result *= i;
    }

    return result;
}

std::set<std::set<int>> binomial_coefficient(std::vector<int> input, int k)
{
    std::set<std::set<int>> solutions;

    for(unsigned int i = 0; i < factorial(input.size()); i++)
    {
        std::next_permutation(input.begin(), input.end());

        solutions.insert(std::set<int>(input.begin(), input.begin() + k));
    }

    return solutions;
}
0
ответ дан 29 November 2019 в 02:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: