std::merge în C++

Combină două intervale sortate într-un singur interval sortat, păstrând toate elementele.

Sintaxă
OutputIt merge(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first);

Ce face std::merge

std::merge parcurge în paralel două intervale deja sortate și scrie la destinație, la fiecare pas, elementul mai mic. Rezultatul este sortat și conține toate elementele din ambele surse, inclusiv dublurile. Lucrează în timp liniar.

Este pasul de bază al sortării prin interclasare (merge sort). Pentru a interclasa două jumătăți sortate ale aceluiași vector, pe loc, există std::inplace_merge.

Parametri

Parametru Descriere
first1, last1 Primul interval sortat.
first2, last2 Al doilea interval sortat.
d_first Destinația, cu loc pentru toate elementele (sau std::back_inserter).

Ce returnează

Iterator după ultimul element scris.

Exemple

Exemplul 1: Interclasarea a două liste de note

#include <algorithm>
#include <iterator>
#include <print>
#include <vector>

int main() {
    std::vector<int> grupa_a{5, 7, 9, 10};
    std::vector<int> grupa_b{6, 7, 8};
    std::vector<int> toate;

    std::merge(grupa_a.begin(), grupa_a.end(), grupa_b.begin(), grupa_b.end(), std::back_inserter(toate));
    std::println("{}", toate);
}

Rezultat

[5, 6, 7, 7, 8, 9, 10]

Exemplul 2: Programări din două cabinete, după oră

#include <algorithm>
#include <iterator>
#include <print>
#include <string>
#include <vector>

struct Programare {
    int ora;
    std::string pacient;
};

int main() {
    std::vector<Programare> cabinet1{{9, "Ana"}, {11, "Ion"}, {14, "Maria"}};
    std::vector<Programare> cabinet2{{10, "Dan"}, {11, "Elena"}};
    std::vector<Programare> zi;

    std::ranges::merge(cabinet1, cabinet2, std::back_inserter(zi), {}, &Programare::ora, &Programare::ora);

    for (const Programare& p : zi) {
        std::println("{:02}:00 {}", p.ora, p.pacient);
    }
}

Rezultat

09:00 Ana
10:00 Dan
11:00 Ion
11:00 Elena
14:00 Maria

Greșeli frecvente

  • Sursele nu sunt sortate: rezultatul nu va fi sortat (și nu primești nicio eroare).
  • Destinația este un vector gol accesat cu begin(). Folosește std::back_inserter sau redimensionează vectorul la suma lungimilor.

Comenzi înrudite

  • std::set_union: Calculează reuniunea a două intervale sortate: elementele care apar în oricare dintre ele, fără dubluri între ele.
  • std::sort: Sortează elementele dintr-un interval, crescător sau după o regulă dată de tine.
  • std::includes: Verifică dacă toate elementele unui interval sortat se află și în alt interval sortat (submulțime).