Search code examples
c++algorithmstdvector

Is there a C++ function which enables to divide vector into three seperate vectors?


I am looking for a solution to divide vector into 3 separate vectors with proportion of elements 9:1:1, for example if we had 1100 elements in original vector then I expect to get 3 vectors with consecutively 900, 100 and 100 elements. There is a function std::partition_copy, however it copies data only to 2 separate vectors.


Solution

  • There is no standard algorithm to do what you want directly. I suppose there are too many special cases to be considered. For example, how to distribute elements according to 9:1:1 when the initial vector has only eg 9 elements? Should each partition contain at least 1 element? Should the result be 7:1:1 or 8:1:0?

    However, you can use std::vectors constructor taking two iterators:

    #include <vector>
    #include <iostream>
    #include <numeric>
    
    int main() {
        
        std::vector<int> v(10);
        std::iota(v.begin(),v.end(),0);
    
        size_t mid1 = v.size()*0.8;
        size_t mid2 = mid1+v.size()*0.1;
    
        std::vector<int> v1{v.begin(),v.begin()+mid1};
        std::vector<int> v2{v.begin()+v1.size(),v.begin()+mid2};
        std::vector<int> v3{v.begin()+v1.size()+v2.size(),v.end()};
    
        for (const auto& e : v1) std::cout << e << " ";
        std::cout << "\n";
        for (const auto& e : v2) std::cout << e << " ";
        std::cout << "\n";
        for (const auto& e : v3) std::cout << e << " ";
        std::cout << "\n";
    }
    

    When the number of items is given in absolute numbers the above issues cannot arise and you could write a generic algorithm that fills n vectors with m_i (0<=i<n) elements from a source vector.

    Last but not least, consider that copying a whole vector, just to be able to access subranges of it, is not very idiomatic. Instead of creating new vectors that contain parts of the elements you should refactor the methods working on those subranges to take iterators instead of vectors, ie

     template <typename Iterator>
     void do_something_with_vector_elements(Iterator begin,Iterator end);
    

    instead of

     void do_something_with_all_vector_elements(const std::vector<int>& v);