Jeder Satz enthält Elemente in einer bestimmten Reihenfolge. Ich möchte eine Schranke für die Größe eines Satzes angeben und automatisch das letzte Element zu löschen, wenn ein neues streng kleiner (in Bezug auf die Reihenfolge) eingesetzt ist und die angegebene Größe ist bereits erreicht.Wie füge ich einen neuen Wert in einen Satz ein und lösche gleichzeitig einen anderen?
Natürlich könnte ich so etwas wie die folgenden tun:
class bounded_set
{
private:
using set = std::set<Key, Compare, Allocator>;
using iterator = typename set::iterator;
public:
bounded_set(std::size_t size)
: m_size(size)
{ }
std::pair<iterator, bool> insert(Key const& value)
{
if (m_set.size() < m_size)
return m_set.insert(value);
auto last = std::prev(m_set.end());
if (Compare()(value, *last))
{
m_set.erase(last);
return m_set.insert(value);
}
return std::make_pair(last, false);
}
private:
set m_set;
std::size_t m_size;
};
Neben der Tatsache, dass bounded_set
ist nicht der beste Name (seit begrenzt Behälter eine bekannte Sache in der Welt der gleichzeitigen Programmierung sind), Mache ich mir Sorgen über die Speicherzuweisung in dieser Implementierung. Höchstwahrscheinlich wird zuerst der von last
verwendete Speicherplatz freigegeben. Aber sofort danach muss neuer Speicher für value
reserviert werden.
Was ich wirklich tun möchte, ist die Verwendung des Speichers für last
zugewiesen und kopieren Sie über die Daten für value
an diesen Ort, unter Beibehaltung der Reihenfolge.
Es ist möglich, dass Sie Ihr Set durch einen Vektor ersetzen können. Wenn Ihr Dataset nicht riesig ist und Schlüssel teure Kopien ohne billige Züge haben, wird die Leistung nicht beeinträchtigt und kann sogar schneller sein, da ein Vektor weniger dynamische Speicherzuweisungen als ein Satz aufweist. Wenn Sie Ihren Vektor sortiert haben, können Sie 'std :: lower_bound' für Log (n) -Suchen verwenden. Natürlich müssen Sie überprüfen, ob der Vektor bereits den Wert enthält, bevor Sie ihn einfügen usw. Umschließen Sie dieses Zeug in eine Klasse "flat_set". –