Selain accumulate dan reduce, header <numeric> menyimpan empat algoritma kecil yang sangat praktis: std::iota untuk mengisi rentang dengan deret bertambah satu, std::inner_product untuk menjumlahkan hasil kali pasangan elemen (dot product), std::partial_sum untuk jumlah berjalan, dan std::adjacent_difference untuk selisih antar elemen bersebelahan. Keempatnya pendek, mudah diingat, dan sering muncul di kode nyata — dari menomori data, menghitung statistik berjalan, hingga membalik transformasi selisih. Chapter ini mendemonstrasikan keduanya dalam satu program yang saling menyambung, ditambah catatan pemisahan tugas dengan chapter Algoritma Numerik di Section Standard Library yang membahas gcd, lcm, dan midpoint.

Mengisi dan Mengagregasi dengan <numeric> #

Program berikut menjalankan keempat algoritma secara berurutan, dan hasilnya membentuk lingkaran yang rapi: deret dijumlahkan berjalan, lalu dibedah kembali menjadi deret semula.

cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

void cetak(const std::vector<int>& v) {
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (i > 0) std::cout << ' ';
        std::cout << v[i];
    }
    std::cout << '\n';
}

int main() {
    // iota: isi rentang dengan 1, 2, 3, ... bertambah satu
    std::vector<int> nomor(6);
    std::iota(nomor.begin(), nomor.end(), 1);
    std::cout << "iota                : ";
    cetak(nomor);

    // inner_product: jumlahkan hasil kali pasangan elemen (dot product)
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {4, 5, 6};
    int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0);
    std::cout << "inner_product       : " << dot << "\n";

    // partial_sum: jumlah berjalan (prefix sum)
    std::vector<int> berjalan;
    std::partial_sum(nomor.begin(), nomor.end(), std::back_inserter(berjalan));
    std::cout << "partial_sum         : ";
    cetak(berjalan);

    // adjacent_difference: selisih tiap pasangan elemen bersebelahan
    std::vector<int> selisih;
    std::adjacent_difference(berjalan.begin(), berjalan.end(),
                             std::back_inserter(selisih));
    std::cout << "adjacent_difference : ";
    cetak(selisih);
    return 0;
}

Output yang Dihasilkan:

text
iota                : 1 2 3 4 5 6
inner_product       : 32
partial_sum         : 1 3 6 10 15 21
adjacent_difference : 1 2 3 4 5 6

Bedah baris demi baris:

  1. Baris 15-16 (std::iota(nomor.begin(), nomor.end(), 1)): mengisi enam elemen vector dengan 1, 2, 3, 4, 5, 6 — nilai awal 1, tiap langkah bertambah satu. Nama iota berasal dari notasi bahasa pemrograman APL untuk deret bilangan.
  2. Baris 20-21 (std::inner_product(a.begin(), a.end(), b.begin(), 0)): mengalikan pasangan elemen 1*4, 2*5, 3*6 lalu menjumlahkannya dengan nilai awal 0, hasil 32. Inilah perhitungan dot product vektor — fondasi banyak rumus grafika dan pembelajaran mesin. Seperti transform binary, rentang kedua hanya diberi titik awal, jadi kita yang bertanggung jawab memastikan panjangnya cukup.
  3. Baris 25-26 (std::partial_sum(...)): elemen ke-n hasilnya adalah jumlah elemen ke-1 sampai ke-n rentang sumber: 1, 3, 6, 10, 15, 21. Ini disebut juga prefix sum, dasar dari banyak teknik efisiensi pada pemrosesan rentang.
  4. Baris 30-32 (std::adjacent_difference(...)): elemen pertama hasil disalin apa adanya, elemen setelahnya adalah x[i] - x[i-1]: 1, 2, 3, 4, 5, 6 — kembali persis deret iota awal.

Baris 3 dan 4 dari bedah itu memperlihatkan pasangan terbalik: partial_sum dan adjacent_difference saling membatalkan. Membekukan perubahan harga harian menjadi jumlah kumulatif (partial_sum) lalu membekasnya kembali menjadi perubahan harian (adjacent_difference) adalah pola nyata dalam analisis data, misalnya mengubah saldo rekening menjadi mutasi harian.

Kombinasi dengan Algoritma Lain #

Keempat algoritma ini memakai konvensi rentang yang sama seperti keluarga <algorithm>, sehingga bisa dirantai bebas. iota menjadi generator data uji yang disukai programmer karena deterministik — angka yang muncul di output selalu sama, tanpa generator acak. partial_sum dengan argumen operasi khusus (misalnya std::multiplies<int>{}) berubah menjadi produk berjalan. Dan inner_product dengan dua operasi khusus dapat dipakai untuk agregasi pasangan yang berbeda dari kali-jumlah, semisal menjumlahkan selisih mutlak dua rentang.

Pemisahan Tugas dengan Section Standard Library #

Satu penjelasan menghindari kebingungan: materi numerik di kursus ini dibagi dua. Chapter Algoritma Numerik pada Section Standard Library membahas fungsi perhitungan titik tunggal — std::gcd, std::lcm, dan std::midpoint — yang menerima angka, bukan rentang. Chapter ini (yang sedang kita baca) membahas algoritma berbasis rentang iterator. Keduanya sama-sama hidup di header <numeric>, tetapi pola pemakaiannya berbeda: fungsi titik menghitung satu jawaban dari beberapa angka, algoritma rentang mengolah seluruh koleksi sekaligus.

Sampai di sini alat pengolahan rentang kita sudah lengkap: mengurutkan, mencari, menghitung, menyalin, mengubah, menghapus, mengelompokkan, dan mengagregasi. Dua chapter terakhir menyiapkan bekal tekniknya: bagaimana menulis comparator kustom dengan benar, lalu function objects sebagai mesin di baliknya.

Rujukan resmi: header <numeric> , std::iota , dan std::inner_product .