Chcę podzielić jeden wektor bajtów do tablicy z równym wektorem bajtów, na przykład, gdybym miał

std::vector<uint8_t> vec{11,22,33,44,55,66,77,88};
std::array<std::vector<uint8_t>, N> arr; // N is the number of subvectors from the vector vec

Jeśli n == 4 Zawartość alr będzie 4 wektory Każdy wektor zawiera 2 elementy {{11,22}, {33,44}, {55,66}, {77,88}}

-2
Makk aouu 23 październik 2020, 15:30

1 odpowiedź

Najlepsza odpowiedź

Ponieważ jest to trudny błąd, jeśli N nie dzieli się równomiernie w vec.size(), jest to w rzeczywistości dość proste do rozwiązania. Podstawowa logika byłaby:

  1. Sprawdź, czy wejście można podzielić poprawnie (rzut na awarie)
  2. Utwórz wektory N w tablicy
  3. Przestrzeń rezerwowa dla vec.size() / N dla każdego wektora w tej tablicy (opcjonalnie)
  4. Przechowuj vec.size() / N z oryginału vec w każdym wektorze (w zasadzie, pętla przez elementy vec.size() / N z vec i przechowywać w wyniku wyników)

Ponieważ wynikiem jest std::array, rozmiar musi być określony statystycznie - co oznacza, że użytkownik może być w stanie określić ten numer, można to zrobić tylko za pomocą parametru bez typu template N. Na przykład:

#include <vector>  // std::vector
#include <cstdint> // std::uint8_t
#include <cstddef> // std::size_t
#include <stdexcept> // std::runtime_error
#include <cassert>   // assert
#include <array> // std::array

template <std::size_t N>
auto split(const std::vector<std::uint8_t>& vec) -> std::array<std::vector<std::uint8_t>, N>
{
    // Handle the error case
    if (vec.size() % N != 0) {
        throw std::runtime_error{"vec.size() is not divisible by N"};
    }

    const auto values_per_container = vec.size() / N;
    auto result = std::array<std::vector<std::uint8_t>, N>{};
    
    auto i = 0u;

    // Iterate through the vectors in the array
    for (auto& v : result) {
        v.reserve(values_per_container);

        // Store 'vec.size() / N' objects per container
        for (auto j = 0; j < values_per_container; ++j, ++i) {
            assert(i < vec.size());

            v.push_back(vec[i]);
        }
    }
    return result;
};

Korzystanie z i Jako indeks tutaj do Itera za pomocą wejścia {X1}} jest bezpieczny, i powinien być niezmiennikiem tego kodu - ponieważ najpierw upewniamy się, że vec.size() / N jest ważny. Stąd tutaj użycie assert

Oto przykład na Eksplorator kompilatora

1
Human-Compiler 23 październik 2020, 16:54