Namespaces
Variants

std::transform_inclusive_scan

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeänderungsoperationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
 
Definiert in Header <numeric>
template< class InputIt, class OutputIt,
          class BinaryOp, class UnaryOp >
OutputIt transform_inclusive_scan
    ( InputIt first, InputIt last, OutputIt d_first,
      BinaryOp binary_op, UnaryOp unary_op );
(1) (seit C++17)
(constexpr seit C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2,
          class BinaryOp, class UnaryOp >
ForwardIt2 transform_inclusive_scan
    ( ExecutionPolicy&& policy,
      ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
      BinaryOp binary_op, UnaryOp unary_op );
(2) (seit C++17)
template< class InputIt, class OutputIt,
          class BinaryOp, class UnaryOp, class T >
OutputIt transform_inclusive_scan
    ( InputIt first, InputIt last, OutputIt d_first,
      BinaryOp binary_op, UnaryOp unary_op, T init );
(3) (seit C++17)
(constexpr seit C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2,
          class BinaryOp, class UnaryOp, class T >
ForwardIt2 transform_inclusive_scan
    ( ExecutionPolicy&& policy,
      ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
      BinaryOp binary_op, UnaryOp unary_op, T init );
(4) (seit C++17)
1) Berechnet die inklusive Präfixsumme mittels op.
Für jede ganze Zahl i in [0, std::distance(first, last)) werden nacheinander die folgenden Operationen ausgeführt:
  1. Es wird eine Sequenz erzeugt, die aus den Werten besteht, die nacheinander von den Elementen von [first, iter] durch unary_op transformiert werden, wobei iter der nächste i-te Iterator von first ist.
  2. Berechnet die verallgemeinerte nichtkommutative Summe der Sequenz über binary_op.
  3. Weist das Ergebnis *dest zu, wobei dest der nächste i-te Iterator von d_first ist.
3) Gleich wie (1), aber jede erzeugte Sequenz wird gebildet aus init gefolgt von den Elementen von [first, iter] in der Reihenfolge.
2,4) Gleich wie (1,3), aber ausgeführt gemäß policy.
Diese Überladungen nehmen nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(seit C++20)

Die verallgemeinerte nichtkommutative Summe einer Sequenz von Elementen bezüglich einer binären Operation binary_op ist wie folgt definiert:

  • Hat die Sequenz nur ein Element, so ist die Summe der Wert des Elements.
  • Andernfalls werden nacheinander die folgenden Operationen ausgeführt:
  1. Wähle zwei beliebige benachbarte Elemente elem1 und elem2 aus der Sequenz.
  2. Berechne binary_op(elem1, elem2) und ersetze die beiden Elemente in der Sequenz durch das Ergebnis.
  3. Wiederhole die Schritte 1 und 2, bis nur noch ein Element in der Sequenz vorhanden ist.


Das Ergebnis ist nichtdeterministisch, wenn binary_op nicht assoziativ ist (z. B. Gleitkomma-Addition).

Für die Überladungen (1,2): Wenn binary_op(unary_op(*first), unary_op(*first)) nicht in den Werttyp von decltype(first) konvertierbar ist, ist das Programm fehlerhaft.

Für die Überladungen (3,4): Wenn einer der folgenden Werte nicht in T konvertierbar ist, ist das Programm fehlerhaft:

  • binary_op(init, init)
  • binary_op(init, unary_op(*first))
  • binary_op(unary_op(*first), unary_op(*first))

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:

  • Für die Überladungen (1,2): Der Werttyp von decltype(first) ist nicht MoveConstructible.
  • Für die Überladungen (3,4): T ist nicht MoveConstructible.
  • unary_op oder binary_op modifiziert ein Element von [first, last).
  • unary_op oder binary_op macht einen Iterator oder Teilbereich von [first, last] ungültig.

Parameter

first, last - das Paar von Iteratoren, das den Bereich der zu summierenden Elemente definiert
d_first - der Anfang des Zielbereichs; kann gleich first sein
policy - die zu verwendende Ausführungsrichtlinie
init - der Anfangswert
unary_op - unäres FunctionObject , das auf jedes Element des Eingabebereichs angewendet wird. Der Rückgabetyp muss als Eingabe für binary_op akzeptabel sein.
binary_op - binäres FunctionObject , das auf das Ergebnis von unary_op , die Ergebnisse anderer binary_op und init (falls angegeben) angewendet wird
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
OutputIt muss die Anforderungen von LegacyOutputIterator erfüllen.
-
ForwardIt1, ForwardIt2 muss die Anforderungen von LegacyForwardIterator erfüllen.

Rückgabewert

Iterator auf das Element nach dem letzten geschriebenen Element.

Komplexität

Gegeben N als std:: distance ( first, last ) :

1-4) O(N) Anwendungen von unary_op und binary_op jeweils.

Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden Fehler wie folgt:

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allozieren kann, wird std::bad_alloc geworfen.

Hinweise

unary_op wird niemals auf init angewendet.

Der Parameter init steht an letzter Stelle, anders als bei std::transform_exclusive_scan , da er für diese Funktion optional ist.

Beispiel

#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
    std::vector data{3, 1, 4, 1, 5, 9, 2, 6};
    auto times_10 = [](int x) { return x * 10; };
    std::cout << "10-fache exklusive Summe: ";
    std::transform_exclusive_scan(data.begin(), data.end(),
                                  std::ostream_iterator<int>(std::cout, " "),
                                  0, std::plus<int>{}, times_10);
    std::cout << "\n10-fache inklusive Summe: ";
    std::transform_inclusive_scan(data.begin(), data.end(),
                                  std::ostream_iterator<int>(std::cout, " "),
                                  std::plus<int>{}, times_10);
    std::cout << '\n';
}

Ausgabe:

10-fache exklusive Summe: 0 30 40 80 90 140 230 250 
10-fache inklusive Summe: 30 40 80 90 140 230 250 310

Siehe auch

berechnet die Teilsumme eines Bereichs von Elementen
(Funktionsschablone)
wendet eine Funktion auf einen Bereich von Elementen an und speichert die Ergebnisse in einem Zielbereich
(Funktionsschablone & Algorithmus-Funktionsobjekt)
ähnlich wie std::partial_sum, bezieht das ith Eingabeelement in die ith Summe ein
(Funktionsschablone)
wendet ein aufrufbares Objekt an und berechnet dann eine exklusive Scan
(Funktionsschablone)