Search code examples
c++c++17

Print n vectors of n-1 elements


I have a vector of data of n elements. I want to print n vectors of n-1 elements where each of these vectors are the original vector data minus 1 element. Basically, it's a jackknife analysis.

For a data vector containing [ 0 1 2 3 ], I want to print the following jackedData vectors:

[ 1 2 3 ]
[ 0 2 3 ]
[ 0 1 3 ]
[ 0 1 2 ]

I've come up with the following:

int Gen()
{
    static int i( 0 );
    return i++;
}

void Print( const int& i )
{
    std::cout << i << " ";
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector< int > data;
    
    std::generate_n( std::back_inserter( data ), 6, Gen );
    std::vector< int > jackedData( data.begin() + 1, data.end() );

    std::vector< int >::const_iterator it_data( data.begin() );
    std::vector< int >::iterator it_jData( jackedData.begin() );

    int i( 0 );

    for ( 
    ; it_jData != jackedData.end()
    ; ++it_data, ++it_jData, ++i )
    {
        std::cout << i << "\t";
        std::for_each( jackedData.begin(), jackedData.end(), Print );
        std::cout << "\n";

        *it_jData = *it_data;
    }
    
    std::cout << i << "\t";
    std::for_each( jackedData.begin(), jackedData.end(), Print );
    std::cout << "\n";

    return 0;
}

The problem is, the print has to be called once outside the loop. If it's not called outside the loop, then there is an off-by-one error.

How can this be done without having to call the print once outside of the loop?


Solution

  • If its allowed to modify the input vector, you can do this -

    Iterate over vector of size n in a loop and in every iteration:

    • Print the last n - 1 elements of vector.
    • After this, swap the first element with element at position -
      current processing vector index + 1.

    Implementation:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    void Print (const int& i) {
        std::cout << i << " ";
    }
    
    int main() {
        std::vector<int> v{0, 1, 2, 3};
        
        for (std::size_t x = 0; x < v.size(); ++x) {
            std::cout << "[ ";
            std::for_each (v.begin() + 1, v.end(), Print);
            std::cout << "]" << std::endl;
            std::swap (v[0], v[(x + 1) % v.size()]);
        }
        return 0;
    }
    

    Output:

    [ 1 2 3 ]
    [ 0 2 3 ]
    [ 0 1 3 ]
    [ 0 1 2 ]