Pytanie limit wielkości kolejki w C ++


Zauważam wątek podobnego pytania: Limit rozmiaru kolejki <T> w .NET? Dokładnie to chcę zrobić, ale nie używam .net, ale GNU C ++. Nie mam odniesienia do klasy bazowej w GNU C ++, więc java lubię super.***() lub .net jak base.***() nie będzie działać. Próbowałem dziedziczyć z klasy kolejek, ale okazało się to na próżno.

Co chcę robić: określ rozmiar kolejki i usuń kolejkę po zapełnieniu kolejki. Aby być konkretnym: jeśli maksymalny rozmiar mojej kolejki wynosi 2, po naciśnięciu trzeciego elementu pierwsza pozycja zostanie automatycznie wyskoczona przed naciśnięciem nowego elementu.

Jak zaimplementować taką kolejkę?

Dzięki.


17
2017-08-13 16:16


pochodzenie


Musisz wyjaśnić, co masz na myśli przez "automatyczną likwidację" - czy masz na myśli odrzucić rzeczy przy głowie kolejki?
@Neil: Już miałem zadać to samo pytanie, ale najpierw wpadłem na link z linkami. :) - sbi


Odpowiedzi:


Utwórz nową klasę, która zamyka kolejkę i wymuś ograniczenie rozmiaru w nowej klasie.


13
2017-08-13 16:18



masz na myśli: tworzenie nowej klasy z kolejką zmiennych członkowskich? - Lily
+1 To wydaje mi się najprostszym rozwiązaniem. - DeusAduro
@Lily, wierzę, że właśnie to robi. Jest to dość proste, ponieważ kolejka ma tylko dwa ważne mutatory: push_back, pop_front. W twoim przypadku, jeśli automatycznie piszę, możesz potrzebować tylko funkcji push_back jako członka publicznego. - DeusAduro
Nie zgadzam się z tym rozwiązaniem, ponieważ uniemożliwia korzystanie z tej kolejki, w której oczekuje się kolejki std lib (jak na przykład: template< typename T, class C> void f(std::queue<T,C>&)). OTOH, użycie `std :: queue z innym bazowym kontenerem pozwoli na użycie tej kolejki z wystarczająco ogólnym kodem, który oczekuje kolejek std lib. - sbi


Wiem, że powiedziałeś "automatycznie", ale, aby zachować prostotę: obuduj tylko Enqueue()w funkcji lokalnej (nie, nie czyste OO, ale działa):

Queue<T> myQueue = new Queue<T>();

void addToMyQueue(T param)
{
   myQueue.Enqueue(param); //or push(param)
   if (myQueue.Count > LIMIT)
      myQueue.Dequeue(); //or pop()
}

void main()
{
   addToMyQueue(param);
}

14
2018-02-22 15:03



Jest to standardowa kolejka i spełnia cel (tj. Stały rozmiar kolejki). Mówię, że to najbardziej czyste rozwiązanie. - wmac
Przy okazji jest to prawdopodobnie format Java. Klasa jest kolejką, a inicjalizacja nie potrzebuje nowej, tylko kolejki <T> myQueue; wystarczy i zamiast tych metod musisz użyć funkcji push, pop i size. - wmac
+1, niezwykle proste. - MDMoore313


Brzmi jak boost :: circuclar_buffer robi to, czego szukasz:

Zapisywanie do pełnego bufora 

Istnieje kilka opcji, jak sobie z tym poradzić   z przypadkiem, jeśli źródło danych   produkuje więcej danych niż mieści się w   bufor o stałym rozmiarze:

  1. Poinformuj źródło danych, aby zaczekał, aż   w buforze jest miejsce (np   wyrzucenie wyjątku przepełnienia).
  2. Jeśli najstarsze dane są najbardziej   ważne, zignoruj ​​nowe dane z   źródło, dopóki nie ma miejsca w   bufor ponownie.
  3. Jeśli najnowsze dane są najważniejsze, napisz na   najstarsze dane.
  4. Niech producent będzie   odpowiedzialny za sprawdzenie wielkości   bufor przed wprowadzeniem do niego.

Oczywiste jest, że    circular_buffer wdraża trzeci   opcja. Ale może być mniej oczywiste   nie implementuje żadnej innej opcji -   szczególnie pierwsze dwa. Można dostać   wrażenie, że    circular_buffer powinien wdrożyć   pierwsze trzy opcje i oferują a   mechanizm wyboru między nimi. To   wrażenie jest złe. The    circular_buffer został zaprojektowany i   zoptymalizowane tak, aby były okrągłe (co oznacza   nadpisywanie najstarszych danych, kiedy   pełny). Jeśli taki mechanizm kontrolny   został włączony, po prostu   komplikują sprawy i użycie   z circular_buffer byłoby   prawdopodobnie mniej proste.


7
2017-08-13 17:05





Zakładając, że przez Queue<T> masz na myśli std::queue<T>: Kolejka jest po prostu adapterem dla kontenera, który jest przekazywany podczas kompilacji. Możesz użyć kontenera, który już robi to, co chcesz. Najlepsze dopasowanie wydaje się być okrągłym buforem, jeśli możesz znaleźć taki, który obsługuje niezbędne operacje std::queue (Sądzę, że to push_back(), pop_front(), i size(), ale nie sprawdziłem).


0
2017-08-13 16:29