Вам не нужно писать собственную реализацию алгоритма. Итераторы - это точка настройки, когда вы хотите использовать существующий алгоритм для пользовательской структуры данных. К сожалению, написание собственного итератора требует довольно много шаблонов. Я думаю, что boost может помочь, но если вы хотите остаться с тем, что предлагает стандартная библиотека, то, насколько я знаю, нет никакого способа написать это самостоятельно.
Следующее должно быть принято с зерном соли. Я предполагаю, что все внутренние векторы имеют одинаковый размер. Я не принимаю во внимание const_iterators
, потому что вам не нужно, чтобы они использовали std::stable_partition
. Я опустил некоторые функции-члены, которые вы должны будете добавить самостоятельно. Алгоритм требует, чтобы итератор придерживался двух названных концепций, а именно LegacyBidirectionalIterator
и ValueSwappable
. Тем не менее, вот как вы можете реализовать итератор, который позволяет перебирать столбцы 2-го вектора:
#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 << " ";
}
Вывод:
2 5
Живой пример
Эффективность не очень большая проблема, матрицы будут относительно небольшими. Я просто хочу найти самый простой и понятный способ сделать это. Желательно без необходимости писать реализацию stable_partition с нуля.
Если матрицы действительно маленькие (скажем, ~ 20x20 элементов) и эффективность на самом деле не имеет значения, то, возможно, проще всего использовать std::stable_partition
только на внутренних векторах. Вы можете транспонировать матрицу, вызвать алгоритм в al oop для всех внутренних векторов, снова транспонировать. Выполнено. Это в основном ~ 10 строк кода. Твой выбор;)