Должен признать, мне очень нравится решение Potatoswatter ... довольно.
Как он продемонстрировал, это не проблема алгоритма, а итерации. Однако его решение не совсем соответствует требованиям, потому что тестирование для end
итерации очень сложно: требуется много внимания при подготовке контейнеров и создании итераторов, чтобы избежать неопределенного поведения.
Я думаю, что проблему можно было бы лучше выразить, используя концепцию, очень похожую на итераторы: представления.
Представление - это интерфейс адаптера для одного или нескольких контейнеров. На самом деле он ничего не содержит (это важная часть). Однако он предоставляет интерфейс, аналогичный интерфейсу контейнера, так что вы можете кодировать с обычными идиомами.
Прекрасное в представлениях - это то, что их часто можно составлять.
Например, один очень простой вид:
/// Only allow to see a range of the container:
/// std::vector<int> v(40, 3); // { 3, 3, 3, ... }
/// auto rv = make_range_view(v, 4, 5);
/// rv exposes the elements in the range [4,9)
/// in debug mode, asserts that the range is sufficiently large
template <typename Container>
class range_view
{
};
Для вашего вопроса вы бы предпочли создать interleave_view
:
/// Allow to interleave elements of 2 containers each at its own pace
/// std::vector<int> v(40, 3);
/// std::set<int> s = /**/;
///
/// auto iv = make_interleave_view(v, 3, s, 1);
/// Takes 3 elements from v, then 1 from s, then 3 from v, etc...
template <typename C1, typename C2>
class interleave_view
{
};
Здесь проблема конечного итератора каким-то образом облегчена, поскольку мы знаем оба контейнера и, таким образом, мы можем сами создавать итераторы, обеспечивая передачу соответствующих параметров.
Конечно, это может стать немного более утомительным, если контейнеры не предлагают эффективный элемент "size" (list
нет, это O (n)).
Однако общий принцип заключается в том, что представление дает вам больше контроля (и позволяет больше проверок) и безопаснее в использовании, поскольку вы точно контролируете создание итераторов.
Обратите внимание, что в C ++ 0x interleave_view
обычно содержит неограниченное число последовательностей.