cpp

examples

examples.cpp⚙️
/**
 * C++ Vectors - Comprehensive Examples
 * 
 * This file demonstrates vector operations in C++ with detailed explanations.
 * Each function focuses on a specific aspect of working with vectors.
 * 
 * Topics covered:
 * 1. Vector Creation and Initialization
 * 2. Accessing Elements
 * 3. Adding and Removing Elements
 * 4. Size and Capacity Management
 * 5. Iterators
 * 6. Common Algorithms
 * 7. 2D Vectors
 * 8. Vector with Custom Objects
 * 9. Performance Optimization
 * 10. Practical Examples
 * 
 * Compile: g++ -std=c++17 -Wall -Wextra examples.cpp -o examples
 * Run: ./examples
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <string>
#include <memory>
#include <iomanip>
#include <functional>
#include <random>

using namespace std;

// Helper function to print vectors
template<typename T>
void printVector(const vector<T>& v, const string& label = "") {
    if (!label.empty()) cout << label << ": ";
    cout << "[";
    for (size_t i = 0; i < v.size(); i++) {
        cout << v[i];
        if (i < v.size() - 1) cout << ", ";
    }
    cout << "]" << endl;
}

// ============================================================
// 1. Vector Creation and Initialization
// ============================================================
void demonstrateCreation() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║         1. VECTOR CREATION AND INITIALIZATION             ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    // Method 1: Empty vector
    vector<int> v1;
    cout << "Empty vector - Size: " << v1.size() << ", Capacity: " << v1.capacity() << endl;
    
    // Method 2: Vector with size
    vector<int> v2(5);  // 5 zeros
    printVector(v2, "v2(5)");
    
    // Method 3: Vector with size and default value
    vector<int> v3(5, 10);  // 5 tens
    printVector(v3, "v3(5, 10)");
    
    // Method 4: Initializer list
    vector<int> v4 = {1, 2, 3, 4, 5};
    printVector(v4, "v4{1,2,3,4,5}");
    
    // Method 5: Copy constructor
    vector<int> v5(v4);
    printVector(v5, "v5(copy of v4)");
    
    // Method 6: Range constructor
    vector<int> v6(v4.begin() + 1, v4.end() - 1);
    printVector(v6, "v6(partial copy)");
    
    // Method 7: From C-style array
    int arr[] = {100, 200, 300};
    vector<int> v7(begin(arr), end(arr));
    printVector(v7, "v7(from array)");
    
    // Method 8: Move constructor (C++11)
    vector<int> v8 = {6, 7, 8};
    vector<int> v9 = move(v8);
    printVector(v9, "v9(moved from v8)");
    cout << "v8 after move - Size: " << v8.size() << " (empty!)" << endl;
    
    // Different types
    vector<string> words = {"Hello", "World", "C++"};
    printVector(words, "String vector");
    
    vector<double> decimals = {1.1, 2.2, 3.3};
    printVector(decimals, "Double vector");
}

// ============================================================
// 2. Accessing Elements
// ============================================================
void demonstrateAccess() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║              2. ACCESSING ELEMENTS                        ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    vector<int> v = {10, 20, 30, 40, 50};
    printVector(v, "Vector");
    
    // Using operator[]
    cout << "\nUsing operator[]:" << endl;
    cout << "  v[0] = " << v[0] << endl;
    cout << "  v[2] = " << v[2] << endl;
    cout << "  v[4] = " << v[4] << endl;
    // v[10] - No bounds checking, dangerous!
    
    // Using at() - with bounds checking
    cout << "\nUsing at() (with bounds checking):" << endl;
    cout << "  v.at(0) = " << v.at(0) << endl;
    cout << "  v.at(2) = " << v.at(2) << endl;
    
    try {
        cout << "  Trying v.at(10)... ";
        int x = v.at(10);
        (void)x;  // Suppress unused warning
    } catch (const out_of_range& e) {
        cout << "Exception: " << e.what() << endl;
    }
    
    // front() and back()
    cout << "\nUsing front() and back():" << endl;
    cout << "  v.front() = " << v.front() << " (first element)" << endl;
    cout << "  v.back() = " << v.back() << " (last element)" << endl;
    
    // Modifying through accessors
    v.front() = 100;
    v.back() = 500;
    printVector(v, "After modifying front/back");
    
    // data() - raw pointer
    cout << "\nUsing data() for raw pointer access:" << endl;
    int* ptr = v.data();
    cout << "  ptr[0] = " << ptr[0] << endl;
    cout << "  *(ptr + 2) = " << *(ptr + 2) << endl;
}

// ============================================================
// 3. Adding and Removing Elements
// ============================================================
void demonstrateModification() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║           3. ADDING AND REMOVING ELEMENTS                 ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    vector<int> v;
    
    // push_back
    cout << "push_back() - Adding to end:" << endl;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    printVector(v, "After push_back(10,20,30)");
    
    // emplace_back (more efficient for complex objects)
    v.emplace_back(40);
    printVector(v, "After emplace_back(40)");
    
    // insert
    cout << "\ninsert() - Adding at position:" << endl;
    v.insert(v.begin() + 1, 15);  // Insert 15 at index 1
    printVector(v, "Insert 15 at index 1");
    
    v.insert(v.begin(), 5);  // Insert at beginning
    printVector(v, "Insert 5 at beginning");
    
    v.insert(v.end(), 50);  // Insert at end (like push_back)
    printVector(v, "Insert 50 at end");
    
    // Insert multiple copies
    v.insert(v.begin() + 3, 3, 100);  // Insert 3 copies of 100
    printVector(v, "Insert 3x100 at index 3");
    
    // Insert range
    vector<int> more = {200, 201, 202};
    v.insert(v.end(), more.begin(), more.end());
    printVector(v, "Insert range at end");
    
    // pop_back
    cout << "\npop_back() - Removing from end:" << endl;
    v.pop_back();
    printVector(v, "After pop_back()");
    
    // erase
    cout << "\nerase() - Removing at position:" << endl;
    v.erase(v.begin() + 3);  // Remove element at index 3
    printVector(v, "Erase at index 3");
    
    v.erase(v.begin(), v.begin() + 2);  // Remove first 2 elements
    printVector(v, "Erase first 2 elements");
    
    // clear
    cout << "\nclear() - Removing all elements:" << endl;
    cout << "Before clear: Size = " << v.size() << ", Capacity = " << v.capacity() << endl;
    v.clear();
    cout << "After clear: Size = " << v.size() << ", Capacity = " << v.capacity() << endl;
    cout << "(Note: capacity unchanged after clear!)" << endl;
}

// ============================================================
// 4. Size and Capacity Management
// ============================================================
void demonstrateSizeCapacity() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║          4. SIZE AND CAPACITY MANAGEMENT                  ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    vector<int> v;
    
    cout << "Initial state:" << endl;
    cout << "  size() = " << v.size() << endl;
    cout << "  capacity() = " << v.capacity() << endl;
    cout << "  empty() = " << boolalpha << v.empty() << endl;
    cout << "  max_size() = " << v.max_size() << endl;
    
    // Observe capacity growth
    cout << "\nCapacity growth during push_back:" << endl;
    cout << setw(10) << "Size" << setw(15) << "Capacity" << endl;
    cout << string(25, '-') << endl;
    
    for (int i = 0; i < 20; i++) {
        size_t oldCap = v.capacity();
        v.push_back(i);
        if (v.capacity() != oldCap) {
            cout << setw(10) << v.size() << setw(15) << v.capacity() << " (reallocated)" << endl;
        }
    }
    
    // reserve
    cout << "\nUsing reserve() to pre-allocate:" << endl;
    vector<int> v2;
    v2.reserve(100);
    cout << "After reserve(100): Size = " << v2.size() << ", Capacity = " << v2.capacity() << endl;
    
    // resize
    cout << "\nUsing resize():" << endl;
    v2.resize(10);
    printVector(v2, "resize(10) - fills with zeros");
    
    v2.resize(15, 99);
    printVector(v2, "resize(15, 99) - extends with 99s");
    
    v2.resize(5);
    printVector(v2, "resize(5) - truncates");
    
    // shrink_to_fit
    cout << "\nUsing shrink_to_fit():" << endl;
    cout << "Before: Size = " << v2.size() << ", Capacity = " << v2.capacity() << endl;
    v2.shrink_to_fit();
    cout << "After: Size = " << v2.size() << ", Capacity = " << v2.capacity() << endl;
}

// ============================================================
// 5. Iterators
// ============================================================
void demonstrateIterators() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║                    5. ITERATORS                           ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    vector<int> v = {10, 20, 30, 40, 50};
    
    // Forward iteration using iterators
    cout << "Forward iteration with iterators:" << endl;
    cout << "  ";
    for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    
    // Using auto (cleaner)
    cout << "Forward iteration with auto:" << endl;
    cout << "  ";
    for (auto it = v.begin(); it != v.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    
    // Reverse iteration
    cout << "Reverse iteration:" << endl;
    cout << "  ";
    for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {
        cout << *rit << " ";
    }
    cout << endl;
    
    // Const iterators
    cout << "Const iteration (cbegin/cend):" << endl;
    cout << "  ";
    for (auto cit = v.cbegin(); cit != v.cend(); ++cit) {
        cout << *cit << " ";
        // *cit = 100;  // Error! Can't modify through const_iterator
    }
    cout << endl;
    
    // Modifying through iterators
    cout << "\nModifying through iterators (doubling values):" << endl;
    for (auto it = v.begin(); it != v.end(); ++it) {
        *it *= 2;
    }
    printVector(v, "After doubling");
    
    // Range-based for loop (C++11)
    cout << "\nRange-based for loop (by value):" << endl;
    cout << "  ";
    for (int x : v) {
        cout << x << " ";
    }
    cout << endl;
    
    // Range-based with reference (can modify)
    cout << "Range-based for loop (by reference, halving):" << endl;
    for (int& x : v) {
        x /= 2;
    }
    printVector(v, "After halving");
    
    // Range-based with const reference (efficient read-only)
    cout << "Range-based with const reference:" << endl;
    cout << "  ";
    for (const auto& x : v) {
        cout << x << " ";
    }
    cout << endl;
    
    // Iterator arithmetic
    cout << "\nIterator arithmetic:" << endl;
    auto it = v.begin();
    cout << "  *it = " << *it << endl;
    cout << "  *(it + 2) = " << *(it + 2) << endl;
    
    it += 3;
    cout << "  After it += 3, *it = " << *it << endl;
    
    auto it2 = v.end() - 1;
    cout << "  *(end - 1) = " << *it2 << " (last element)" << endl;
    
    cout << "  Distance from begin to end: " << distance(v.begin(), v.end()) << endl;
}

// ============================================================
// 6. Common Algorithms
// ============================================================
void demonstrateAlgorithms() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║                 6. COMMON ALGORITHMS                      ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    vector<int> v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    printVector(v, "Original vector");
    
    // Sorting
    cout << "\nSorting:" << endl;
    sort(v.begin(), v.end());
    printVector(v, "Ascending sort");
    
    sort(v.begin(), v.end(), greater<int>());
    printVector(v, "Descending sort");
    
    // Custom sort
    sort(v.begin(), v.end(), [](int a, int b) {
        return (a % 2) < (b % 2);  // Evens before odds
    });
    printVector(v, "Evens before odds");
    
    // Reset for other examples
    v = {5, 2, 8, 1, 9, 3, 7, 4, 6, 2};
    printVector(v, "\nReset vector");
    
    // Finding
    cout << "\nSearching:" << endl;
    auto it = find(v.begin(), v.end(), 8);
    if (it != v.end()) {
        cout << "  Found 8 at index: " << distance(v.begin(), it) << endl;
    }
    
    it = find(v.begin(), v.end(), 100);
    cout << "  Found 100: " << boolalpha << (it != v.end()) << endl;
    
    // Binary search (requires sorted)
    sort(v.begin(), v.end());
    printVector(v, "Sorted for binary search");
    bool exists = binary_search(v.begin(), v.end(), 5);
    cout << "  binary_search(5): " << exists << endl;
    
    // Lower/upper bound
    auto lb = lower_bound(v.begin(), v.end(), 5);
    auto ub = upper_bound(v.begin(), v.end(), 5);
    cout << "  lower_bound(5) at index: " << distance(v.begin(), lb) << endl;
    cout << "  upper_bound(5) at index: " << distance(v.begin(), ub) << endl;
    
    // Min/Max
    cout << "\nMin/Max:" << endl;
    cout << "  min_element: " << *min_element(v.begin(), v.end()) << endl;
    cout << "  max_element: " << *max_element(v.begin(), v.end()) << endl;
    
    auto [minIt, maxIt] = minmax_element(v.begin(), v.end());
    cout << "  minmax: " << *minIt << ", " << *maxIt << endl;
    
    // Count
    cout << "\nCounting:" << endl;
    cout << "  count(2): " << count(v.begin(), v.end(), 2) << endl;
    cout << "  count_if(even): " << count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }) << endl;
    
    // Accumulate (sum)
    cout << "\nAccumulate:" << endl;
    int sum = accumulate(v.begin(), v.end(), 0);
    cout << "  Sum: " << sum << endl;
    
    int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());
    cout << "  Product: " << product << endl;
    
    // Transform
    cout << "\nTransform:" << endl;
    vector<int> squared(v.size());
    transform(v.begin(), v.end(), squared.begin(), [](int x) { return x * x; });
    printVector(squared, "Squared");
    
    // Remove duplicates
    cout << "\nRemoving duplicates:" << endl;
    v = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
    printVector(v, "Before unique");
    auto newEnd = unique(v.begin(), v.end());
    v.erase(newEnd, v.end());
    printVector(v, "After unique");
    
    // Reverse
    cout << "\nReverse:" << endl;
    reverse(v.begin(), v.end());
    printVector(v, "Reversed");
    
    // Fill
    cout << "\nFill and generate:" << endl;
    fill(v.begin(), v.end(), 42);
    printVector(v, "Filled with 42");
    
    // Iota (sequential values)
    vector<int> seq(10);
    iota(seq.begin(), seq.end(), 1);
    printVector(seq, "iota(1 to 10)");
    
    // Shuffle
    cout << "\nShuffle:" << endl;
    random_device rd;
    mt19937 gen(rd());
    shuffle(seq.begin(), seq.end(), gen);
    printVector(seq, "Shuffled");
}

// ============================================================
// 7. 2D Vectors
// ============================================================
void demonstrate2DVector() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║                    7. 2D VECTORS                          ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    // Creating 2D vectors
    cout << "Creating 2D vectors:" << endl;
    
    // Method 1: Initializer list
    vector<vector<int>> matrix1 = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    
    cout << "Matrix from initializer list:" << endl;
    for (const auto& row : matrix1) {
        cout << "  ";
        for (int val : row) {
            cout << setw(3) << val;
        }
        cout << endl;
    }
    
    // Method 2: Size with default value
    int rows = 4, cols = 5;
    vector<vector<int>> matrix2(rows, vector<int>(cols, 0));
    cout << "\n4x5 matrix of zeros:" << endl;
    for (const auto& row : matrix2) {
        cout << "  ";
        for (int val : row) {
            cout << setw(3) << val;
        }
        cout << endl;
    }
    
    // Accessing and modifying
    cout << "\nAccessing elements:" << endl;
    cout << "  matrix1[1][1] = " << matrix1[1][1] << endl;
    matrix1[1][1] = 50;
    cout << "  After matrix1[1][1] = 50: " << matrix1[1][1] << endl;
    
    // Size information
    cout << "\nSize information:" << endl;
    cout << "  Rows: " << matrix1.size() << endl;
    cout << "  Cols: " << matrix1[0].size() << endl;
    
    // Adding rows
    cout << "\nAdding rows:" << endl;
    matrix1.push_back({10, 11, 12});
    cout << "After adding row {10, 11, 12}:" << endl;
    for (const auto& row : matrix1) {
        cout << "  ";
        for (int val : row) {
            cout << setw(3) << val;
        }
        cout << endl;
    }
    
    // Jagged array (rows of different lengths)
    cout << "\nJagged array:" << endl;
    vector<vector<int>> jagged;
    jagged.push_back({1});
    jagged.push_back({2, 3});
    jagged.push_back({4, 5, 6});
    jagged.push_back({7, 8, 9, 10});
    
    for (const auto& row : jagged) {
        cout << "  ";
        for (int val : row) {
            cout << val << " ";
        }
        cout << endl;
    }
    
    // Matrix operations example
    cout << "\nMatrix transpose:" << endl;
    vector<vector<int>> original = {
        {1, 2, 3},
        {4, 5, 6}
    };
    
    int origRows = original.size();
    int origCols = original[0].size();
    vector<vector<int>> transposed(origCols, vector<int>(origRows));
    
    for (int i = 0; i < origRows; i++) {
        for (int j = 0; j < origCols; j++) {
            transposed[j][i] = original[i][j];
        }
    }
    
    cout << "Original (2x3):" << endl;
    for (const auto& row : original) {
        cout << "  ";
        for (int val : row) cout << setw(3) << val;
        cout << endl;
    }
    
    cout << "Transposed (3x2):" << endl;
    for (const auto& row : transposed) {
        cout << "  ";
        for (int val : row) cout << setw(3) << val;
        cout << endl;
    }
}

// ============================================================
// 8. Vector with Custom Objects
// ============================================================
class Student {
public:
    string name;
    int age;
    double gpa;
    
    Student(string n = "", int a = 0, double g = 0.0)
        : name(n), age(a), gpa(g) {}
    
    friend ostream& operator<<(ostream& os, const Student& s) {
        return os << "{" << s.name << ", " << s.age << ", " << s.gpa << "}";
    }
    
    bool operator<(const Student& other) const {
        return gpa > other.gpa;  // Higher GPA first
    }
};

void demonstrateCustomObjects() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║          8. VECTOR WITH CUSTOM OBJECTS                    ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    // Vector of objects
    vector<Student> students;
    
    // Adding objects
    cout << "Adding students:" << endl;
    students.push_back(Student("Alice", 20, 3.8));
    students.push_back(Student("Bob", 21, 3.5));
    students.emplace_back("Charlie", 19, 3.9);  // More efficient
    students.emplace_back("Diana", 22, 3.7);
    
    cout << "Students:" << endl;
    for (const auto& s : students) {
        cout << "  " << s << endl;
    }
    
    // Sorting objects
    cout << "\nSorted by GPA (descending):" << endl;
    sort(students.begin(), students.end());  // Uses operator<
    for (const auto& s : students) {
        cout << "  " << s << endl;
    }
    
    // Custom sort
    cout << "\nSorted by age:" << endl;
    sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
        return a.age < b.age;
    });
    for (const auto& s : students) {
        cout << "  " << s << endl;
    }
    
    // Finding
    cout << "\nFinding student by name:" << endl;
    auto it = find_if(students.begin(), students.end(), [](const Student& s) {
        return s.name == "Bob";
    });
    if (it != students.end()) {
        cout << "  Found: " << *it << endl;
    }
    
    // Using pointers (raw) - not recommended
    cout << "\nVector of raw pointers (manual memory management):" << endl;
    vector<Student*> studentPtrs;
    studentPtrs.push_back(new Student("Eve", 21, 3.6));
    studentPtrs.push_back(new Student("Frank", 20, 3.4));
    
    for (auto ptr : studentPtrs) {
        cout << "  " << *ptr << endl;
    }
    
    // Clean up raw pointers!
    for (auto ptr : studentPtrs) {
        delete ptr;
    }
    studentPtrs.clear();
    
    // Using smart pointers (recommended)
    cout << "\nVector of smart pointers (automatic cleanup):" << endl;
    vector<unique_ptr<Student>> smartStudents;
    smartStudents.push_back(make_unique<Student>("Grace", 22, 3.85));
    smartStudents.push_back(make_unique<Student>("Henry", 21, 3.75));
    
    for (const auto& ptr : smartStudents) {
        cout << "  " << *ptr << endl;
    }
    // No manual cleanup needed!
}

// ============================================================
// 9. Performance Optimization
// ============================================================
void demonstratePerformance() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║            9. PERFORMANCE OPTIMIZATION                    ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    const int N = 100000;
    
    // Without reserve
    cout << "Without reserve():" << endl;
    vector<int> v1;
    int reallocations1 = 0;
    size_t prevCap1 = 0;
    
    for (int i = 0; i < N; i++) {
        if (v1.capacity() != prevCap1) {
            reallocations1++;
            prevCap1 = v1.capacity();
        }
        v1.push_back(i);
    }
    cout << "  Reallocations: " << reallocations1 << endl;
    cout << "  Final capacity: " << v1.capacity() << endl;
    
    // With reserve
    cout << "\nWith reserve(N):" << endl;
    vector<int> v2;
    v2.reserve(N);
    int reallocations2 = 0;
    size_t prevCap2 = v2.capacity();
    
    for (int i = 0; i < N; i++) {
        if (v2.capacity() != prevCap2) {
            reallocations2++;
            prevCap2 = v2.capacity();
        }
        v2.push_back(i);
    }
    cout << "  Reallocations: " << reallocations2 << endl;
    cout << "  Final capacity: " << v2.capacity() << endl;
    
    // emplace_back vs push_back
    cout << "\nemplace_back vs push_back:" << endl;
    cout << "  For complex objects, emplace_back constructs in-place" << endl;
    cout << "  push_back creates a temporary, then copies/moves" << endl;
    
    vector<pair<int, string>> pairs;
    pairs.push_back(make_pair(1, "one"));     // Creates temp pair
    pairs.emplace_back(2, "two");              // Constructs directly
    
    // Move semantics
    cout << "\nMove semantics:" << endl;
    vector<string> source = {"hello", "world", "cpp"};
    cout << "  Source before move: size = " << source.size() << endl;
    
    vector<string> dest = move(source);
    cout << "  Source after move: size = " << source.size() << endl;
    cout << "  Dest after move: size = " << dest.size() << endl;
    
    // Shrink to fit
    cout << "\nshrink_to_fit():" << endl;
    vector<int> v3(1000);
    v3.resize(10);
    cout << "  After resize(10): size = " << v3.size() << ", capacity = " << v3.capacity() << endl;
    v3.shrink_to_fit();
    cout << "  After shrink_to_fit: size = " << v3.size() << ", capacity = " << v3.capacity() << endl;
}

// ============================================================
// 10. Practical Examples
// ============================================================
void demonstratePractical() {
    cout << "\n╔═══════════════════════════════════════════════════════════╗" << endl;
    cout << "║              10. PRACTICAL EXAMPLES                       ║" << endl;
    cout << "╚═══════════════════════════════════════════════════════════╝\n" << endl;
    
    // Example 1: Filtering
    cout << "Example 1: Filtering even numbers" << endl;
    vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    vector<int> evens;
    
    copy_if(numbers.begin(), numbers.end(), back_inserter(evens),
            [](int x) { return x % 2 == 0; });
    printVector(evens, "Even numbers");
    
    // Example 2: Mapping/Transform
    cout << "\nExample 2: Mapping strings to lengths" << endl;
    vector<string> words = {"apple", "banana", "cherry", "date"};
    vector<size_t> lengths(words.size());
    
    transform(words.begin(), words.end(), lengths.begin(),
              [](const string& s) { return s.length(); });
    
    for (size_t i = 0; i < words.size(); i++) {
        cout << "  " << words[i] << " -> " << lengths[i] << endl;
    }
    
    // Example 3: Grouping
    cout << "\nExample 3: Partitioning odds and evens" << endl;
    vector<int> nums = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    printVector(nums, "Before partition");
    
    auto pivot = partition(nums.begin(), nums.end(), [](int x) { return x % 2 == 0; });
    printVector(nums, "After partition (evens first)");
    cout << "  Partition point: " << distance(nums.begin(), pivot) << endl;
    
    // Example 4: Stack using vector
    cout << "\nExample 4: Stack simulation" << endl;
    vector<int> stack;
    
    // Push
    stack.push_back(10);
    stack.push_back(20);
    stack.push_back(30);
    printVector(stack, "Stack after pushes");
    
    // Pop
    int top = stack.back();
    stack.pop_back();
    cout << "Popped: " << top << endl;
    printVector(stack, "Stack after pop");
    
    // Example 5: Queue using vector (not efficient, just demo)
    cout << "\nExample 5: Remove all occurrences of a value" << endl;
    vector<int> data = {1, 2, 3, 2, 4, 2, 5, 2};
    printVector(data, "Before removing 2s");
    
    // Erase-remove idiom
    data.erase(remove(data.begin(), data.end(), 2), data.end());
    printVector(data, "After removing 2s");
    
    // Example 6: Merge sorted vectors
    cout << "\nExample 6: Merge sorted vectors" << endl;
    vector<int> a = {1, 3, 5, 7};
    vector<int> b = {2, 4, 6, 8};
    vector<int> merged;
    
    merge(a.begin(), a.end(), b.begin(), b.end(), back_inserter(merged));
    printVector(merged, "Merged");
    
    // Example 7: Set operations
    cout << "\nExample 7: Set operations on sorted vectors" << endl;
    vector<int> s1 = {1, 2, 3, 4, 5};
    vector<int> s2 = {3, 4, 5, 6, 7};
    vector<int> result;
    
    set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(result));
    printVector(result, "Intersection");
    
    result.clear();
    set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(result));
    printVector(result, "Union");
    
    result.clear();
    set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(result));
    printVector(result, "Difference (s1 - s2)");
}

// ============================================================
// Main Function
// ============================================================
int main() {
    cout << "╔═════════════════════════════════════════════════════════════╗" << endl;
    cout << "║          C++ VECTORS - COMPREHENSIVE EXAMPLES              ║" << endl;
    cout << "╚═════════════════════════════════════════════════════════════╝" << endl;
    
    demonstrateCreation();
    demonstrateAccess();
    demonstrateModification();
    demonstrateSizeCapacity();
    demonstrateIterators();
    demonstrateAlgorithms();
    demonstrate2DVector();
    demonstrateCustomObjects();
    demonstratePerformance();
    demonstratePractical();
    
    cout << "\n╔═════════════════════════════════════════════════════════════╗" << endl;
    cout << "║                    END OF EXAMPLES                         ║" << endl;
    cout << "╚═════════════════════════════════════════════════════════════╝" << endl;
    
    return 0;
}
Examples - C++ Tutorial | DeepML