std::inner_product în C++

Calculează produsul scalar: suma produselor elementelor aflate pe aceleași poziții în două intervale.

Sintaxă
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init);
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init, BinaryOp1 suma, BinaryOp2 produs);

Ce face std::inner_product

std::inner_product calculează init + a[0]*b[0] + a[1]*b[1] + .... Este folosit pentru produsul scalar al vectorilor, dar și pentru totaluri de tip cantitate × preț sau medii ponderate.

Cu ultimele două argumente înlocuiești adunarea și înmulțirea cu alte operații, de exemplu pentru a număra pozițiile pe care două intervale diferă. Ca la accumulate, tipul rezultatului este tipul lui init.

Parametri

Parametru Descriere
first1, last1 Primul interval.
first2 Începutul celui de-al doilea interval (cel puțin la fel de lung).
init Valoarea de pornire.
suma, produs Opționale. Operațiile folosite în loc de + și *.

Ce returnează

Rezultatul acumulat.

Exemple

Exemplul 1: Media ponderată a notelor

#include <numeric>
#include <print>
#include <vector>

int main() {
    std::vector<double> note{9.0, 7.5, 10.0};
    std::vector<double> credite{5, 4, 6};

    double puncte = std::inner_product(note.begin(), note.end(), credite.begin(), 0.0);
    double total_credite = std::accumulate(credite.begin(), credite.end(), 0.0);

    std::println("Media ponderată: {:.2f}", puncte / total_credite);
}

Rezultat

Media ponderată: 9.00

Exemplul 2: Câte răspunsuri diferă

„Suma” este std::plus, iar „produsul” este std::not_equal_to, care dă 1 pentru fiecare poziție diferită.

#include <functional>
#include <numeric>
#include <print>
#include <string>

int main() {
    std::string corect = "ABCDA";
    std::string elev = "ABDDC";

    int gresite = std::inner_product(corect.begin(), corect.end(), elev.begin(), 0, std::plus<>(),
                                     std::not_equal_to<>());
    std::println("Răspunsuri greșite: {}", gresite);
}

Rezultat

Răspunsuri greșite: 2

Greșeli frecvente

  • Al doilea interval este mai scurt decât primul: se citește în afara lui (comportament nedefinit).
  • Pornești de la 0 cu date double și pierzi zecimalele, la fel ca la accumulate.

Comenzi înrudite

  • std::transform_reduce: Transformă fiecare element și combină rezultatele într-o singură valoare, într-o singură trecere.
  • std::accumulate: Adună toate elementele unui interval pornind de la o valoare inițială (sau le combină cu o operație dată).
  • std::transform: Aplică o funcție fiecărui element și scrie rezultatele în alt interval (sau în același).