Finde alle Zahlen in dem Bereich [a, b], die nicht in der gegebenen std :: set S sind

8

Lassen Sie a und b ganze Zahlen sein, a < b . Mit einem std::set<int> S ist eine effiziente und elegante (vorzugsweise ohne explizite Schleifen) Möglichkeit, alle Zahlen aus vector , die nicht in [a, b] sind, zu finden und zu speichern (in S ) .

Lösung 1:

%Vor%

Lösung 2:

Verschiebe alle Zahlen von a nach b in ein set und verwende std::set_difference

Solution1 enthält eine explizite Schleife, und solution2 scheint nicht sehr effizient zu sein (zumindest in Bezug auf den Speicher). Was würdest du vorschlagen? Ich bin auf der Suche nach einem eleganten STL-ish (Boost ist auch akzeptabel) idiomatische Weise, dies zu tun.

    
Armen Tsirunyan 17.05.2012, 12:28
quelle

4 Antworten

8

Sie können etwas wie Ihre Lösung # 2 tun. Aber anstatt einen tatsächlichen Container mit dem Bereich [a,b] zu erstellen, verwenden Sie boost::irange , was ein virtueller Container für einen numerischen Bereich ist. Auf diese Weise haben Sie keine expliziten Schleifen, es wird in linearer Zeit ausgeführt und nicht zu viel Speicher.

Um es noch schneller zu machen, decken Sie nur den relevanten Teil des Sets ab, indem Sie lower_bound / upper_bound :

verwenden %Vor%

Oder mit Boost.Range s set_difference :

%Vor%     
interjay 17.05.2012, 12:45
quelle
2

Nun, das Folgende vermeidet eine Schleife, aber ich bin mir nicht sicher, wonach Sie suchen:

%Vor%

Gibt es auch keine Schleife, die alle Ganzzahlen [a, b] in ein std :: set in Ihrer Lösung 2 einfügt?

    
Dan 17.05.2012 12:43
quelle
2

Das "set" in set_intersection bedeutet nicht std::set - es bedeutet einfach eine logische Menge; eine Gruppe von Dingen. Wenn beide Sammlungen sortiert sind, können Sie einfach set_intersection die beiden in einen dritten Container einfügen.

%Vor%

BEARBEITEN:

Hier ist ein vollständiges Beispiel, das das obige veranschaulicht. Dies verwendet C ++ 11 Lambdas, aber wenn Sie nicht C ++ 11 haben oder keine Lambdas verwenden können, können Sie stattdessen Funktoren verwenden. Beachten Sie das Fehlen expliziter Schleifen.

%Vor%

Ausgabe ist:

%Vor%     
John Dibling 17.05.2012 12:42
quelle
1

Sie könnten von S.lower_bound(a) nach S.lower_bound(b) iterieren und alle Ganzzahlen sammeln, die Sie nicht finden:

%Vor%

Es enthält eine explizite Schleife, aber irgendwie müssen Sie alle Ganzzahlen in [a,b] betrachten.

    
sth 17.05.2012 12:41
quelle

Tags und Links