Kombinieren von C ++ - Standardalgorithmen durch einmaliges Schleifen

8

Ich habe derzeit diesen Code eingerichtet und ausgeführt:

%Vor%

Ich möchte es kompakter und lesbarer machen:

  1. Bestehende C ++ - Standardalgorithmen (*)
  2. erstellen
  3. Führe die Schleife nur einmal durch

(*) Ich gehe davon aus, dass die Kombination bestehender Algorithmen meinen Code lesbarer macht ...

Eine alternative Lösung

Zusätzlich zur Definition eines benutzerdefinierten Algorithmus transform_until , wie von jrok vorgeschlagen, könnte es möglich sein, einen benutzerdefinierten Iteratoradapter zu definieren, der mit dem zugrunde liegenden Iterator iteriert, aber den Operator * () neu definiert, indem er die zugrunde liegende Referenz vor der Rückgabe ändert . So ähnlich:

%Vor%

Natürlich ist das immer noch sehr roh, aber es sollte die Idee geben. Mit dem obigen Adapter könnte ich dann folgendes schreiben:

%Vor%

mit den folgenden im Voraus definiert (was könnte durch einige Vorlage Magie vereinfacht werden):

%Vor%

Wenn der Standard einen solchen Adapter enthalten würde, würde ich ihn verwenden, weil das bedeuten würde, dass er fehlerfrei ist, aber da dies nicht der Fall ist, werde ich meine Schleife wahrscheinlich so behalten wie sie ist.

Ein solcher Adapter würde es erlauben, existierende Algorithmen wiederzuverwenden und auf verschiedene Arten zu mischen, was heute nicht möglich ist, aber es könnte auch Nachteile haben, die ich im Moment wahrscheinlich übersehen werde ...

    
José Mari 27.12.2012, 12:59
quelle

2 Antworten

9

Ich glaube nicht, dass es einen sauberen Weg gibt, dies mit einem einzigen Standardalgorithmus zu tun. Keiner, von dem ich weiß, nimmt ein Prädikat (Sie brauchen eines, um zu entscheiden, wann früh gebrochen werden soll) und erlaubt, die Elemente der Quellsequenz zu ändern.

Sie können Ihren eigenen generischen Algorithmus schreiben, wenn Sie es wirklich "normal" machen wollen. Nennen wir es, hmm, transform_until :

%Vor%

Es ist strittig, ob das besser ist als das, was du hast :) Manchmal ist eine einfache Schleife die beste Lösung.

    
jrok 27.12.2012, 14:06
quelle
0

Nachdem ich Ihre Frage besser verstanden habe, habe ich eine Idee, die funktioniert, aber Boost .

Sie könnten einen transform_iterator verwenden, der toupper aufruft alle Zeichen und benutze das als Inputiterator für find_if oder remove_if . Ich kenne Boost nicht genug, um ein Beispiel zu geben.

Wie @jrok darauf hinweist, transformiert der transform_iterator den Wert nur während der Iteration und ändert den ursprünglichen Container nicht. Um dies zu umgehen, sollten Sie, statt in der gleichen Reihenfolge zu arbeiten, eine neue Kopie erstellen, beispielsweise mit remove_copy_if . Dies kopiert, solange das Prädikat NICHT wahr ist, also wird std::not1 benötigt. Dies würde den remove_if -Fall ersetzen.

Verwenden Sie std::copy , um zu kopieren, bis der Iterator von std::find_if zurückgegeben wird, damit der andere Fall funktioniert.

Schließlich, wenn Ihre Ausgabezeichenfolge leer ist, wird ein std::inserter -Typ des Iterators für die Ausgabe benötigt.

    
Karthik T 27.12.2012 13:09
quelle

Tags und Links