Стабильное разделение std::vector по четности исходного положения элементаC++

Программы на C++. Форум разработчиков
Anonymous
Стабильное разделение std::vector по четности исходного положения элемента

Сообщение Anonymous »

Я хотел бы разделить std::vector по четности исходного индекса элемента в контейнере. Другими словами, я хотел бы разделить его на две половины: первая будет содержать все элементы с четным индексом, а вторая — все элементы с нечетным индексом.

Отношения порядка между элементами не имеют значения, важно только положение в исходном векторе.

Я хотел бы добиться этого эффекта с помощью стандартных алгоритмов и лямбда-выражений, желательно на месте. Я могу сделать это с помощью обычного цикла for.

Пример

Предположим, у нас есть вектор элементов a b c d e f. Желаемое разделение — a c e b d f. Первый (), третий () и пятый () элемент перемещается вперед, а второй (), четвёртый () и шестой () перемещается назад.

Мои попытки

У меня есть объект, похожий на этот:

Код: Выделить всё

struct T {
int x;
};
Мне удалось разделить его по значению поля следующим образом:

Код: Выделить всё

std::vector ts {{1}, {2}, {4}, {3}, {6}, {5}};
auto predicate = [](const T& t) {
return t.x % 2 == 1;
};
std::stable_partition(ts.begin(), ts.end(), predicate);
Результат: 1 3 5 2 4 6. Я хочу, чтобы разделение возвращало 1 4 6 2 3 5.

Я пытался определить предикат как

Код: Выделить всё

auto predicate = [](const std::vector::const_iterator& t)
return t->x % 2 == 1;
};
Но он не компилируется и явно не имеет никакого смысла.

Чтобы проиллюстрировать мою проблему, я написал цикл for, который выполняет такое разбиение, хотя и не стабильным образом.

Код: Выделить всё

for (auto i = ts.begin() + 1, j = ts.begin() + 2; j != ts.end(); i += 1, j += 2) {
std::swap(*i, *j);
}
Резюме

Можно ли добиться этого с помощью алгоритмов std или мне нужно прибегнуть к стандартному циклу?


Подробнее здесь: https://stackoverflow.com/questions/599 ... l-position

Вернуться в «C++»