You don't need to write your own implementation of the algorithm. Iterators are the customization point when you want to use an existing algorithm for a custom data structure. Unfortunately, writing your own iterator requires quite some boilerplate. I think boost can help, but if you want to stay with what the standard library offers, to my knowledge there is no way around writing it yourself.
The following is to be taken with a grain of salt. I assume all inner vectors are of same size. I do not take into account const_iterators
, because you wont need them to use std::stable_partition
. I have omitted some member functions that you will have to add yourself. The algorithm requires the iterator to adhere to two named concepts, namely LegacyBidirectionalIterator
and ValueSwappable
. That being said, here is how you can implement an iterator that enables you to iterate columns of the 2d vector:
#include <iostream>
#include <vector>
struct vector2d_col_iterator {
using container_t = std::vector<std::vector<int>>;
container_t& container;
size_t row;
size_t col;
vector2d_col_iterator& operator++(){
++row;
return *this;
}
bool operator==(const vector2d_col_iterator& other) const {
return col == other.col && row == other.row;
}
bool operator !=(const vector2d_col_iterator& other) const {
return !(*this == other);
}
int& operator*() { return container[row][col]; }
static vector2d_col_iterator begin(container_t& container,int col) {
return {container,0,col};
}
static vector2d_col_iterator end(container_t& container,int col) {
return {container,container.size(),col};
}
};
int main() {
std::vector<std::vector<int>> v{ {1,2,3},{4,5,6}};
auto begin = vector2d_col_iterator::begin(v,1);
auto end = vector2d_col_iterator::end(v,1);
for ( ; begin != end; ++begin) std::cout << *begin << " ";
}
Output:
2 5
Live example
Efficiency is not a really big issue, the matrices will be relatively small. I just want to find the simplest, clearest way of doing this. Preferably without having to write a stable_partition implementation from scratch.
If the matrices are really small (lets say ~20x20 elements) and efficiency is really not a concern, then the simplest is perhaps to use std::stable_partition
only on the inner vectors. You can transpose the matrix, call the algorithm in a loop for all inner vectors, transpose again. Done. Thats basically ~10 lines of code. Your choice ;)