В направлении ответа Bradgonesurfing, много раз одному действительно не нужно для объединения двух векторов, а вместо этого просто работайте с ними, как если бы они были объединены .Это похоже на ваш случай, и это может быть сделано без использования библиотек Boost.
Хитрость заключается в создании векторного прокси-сервера: класса-оболочки, который манипулирует ссылками на оба вектора, видимыми извнекак единый, непрерывный, к которому затем можно получить доступ / пройти точно так же, как вы бы делали на реальном векторе.
ИСПОЛЬЗОВАНИЕ
std::vector<int> A{ 1, 2, 3, 4, 5};
std::vector<int> B{ 10, 20, 30 };
VecProxy<int> AB(A, B); // ----> O(1)
for (size_t i = 0; i < AB.size(); i++)
std::cout << AB[i] << " "; // ----> Output: 1 2 3 4 5 10 20 30
std::cout << AB[6]; // ----> Output: 20
РЕАЛИЗАЦИЯ
template <class T>
class VecProxy {
private:
std::vector<T>& v1;
std::vector<T>& v2;
public:
VecProxy(std::vector<T>& ref1, std::vector<T>& ref2) : v1(ref1), v2(ref2) {}
T& operator[](const size_t& i);
const T& operator[](const size_t& i) const;
const size_t size() const;
};
template<class T>
T& VecProxy<T>::operator[](const size_t& i){
return (i < v1.size()) ? v1[i] : v2[i - v1.size()];
};
template <class T>
const T& VecProxy<T>::operator[](const size_t& i) const{
return (i < v1.size()) ? v1[i] : v2[i - v1.size()];
};
template <class T>
const size_t VecProxy<T>::size() const { return v1.size() + v2.size(); };
ОСНОВНАЯ ВЫГОДА
Это O (1) (постоянное время) для его создания и с минимальным выделением дополнительной памяти.На практике это быстрая операция даже при рассмотрении огромных векторов, поскольку вы заменяете | B |(или | A | + | B |) копирует элемент на ноль.Кроме того, он обеспечивает именно желаемое поведение.
Конкатенация векторов составляет не менее O (| B |) (когда B добавляется к A), независимо от применяемой методики.В вашем случае, поскольку вы намереваетесь работать с третьим вектором, AB, это O (| A | + | B |).В зависимости от размера векторов и количества необходимых операций конкатенации, это может быть узким местом.Приведенный выше трюк обращается к нему.
НЕКОТОРЫЕ ВЕЩИ ДЛЯ РАССМОТРЕНИЯ
- Вы должны пойти на это, только если вы действительно знаете, что делаете, когдазанимаюсь ссылками . Это решение предназначено для конкретной цели поставленного вопроса, для которого оно работает довольно хорошо .Использование его в любом другом контексте может привести к неожиданному поведению, если вы не уверены в том, как работают ссылки.
- В этом примере AB предоставляет не только постоянный, но и неконстантный доступ.Не стесняйтесь удалить это.Поскольку AB содержит ссылки, присвоение ему значений также повлияет на исходные элементы в A и / или B. Независимо от того, является ли это желательной функцией, это вопрос для конкретного приложения, который следует тщательно рассмотреть.
- Аналогично,любые изменения в A или B (такие как присвоение значений, изменение размера и т. д.) также «изменят» AB.Это не обязательно плохо (на самом деле, это может быть очень удобно: AB не нужно явно обновлять, чтобы синхронизировать себя как с A, так и с B), но это, безусловно, поведение, о котором нужно знать.
- Поскольку каждому доступу к элементу предшествует тест (а именно, «i
- Этот подход может быть обобщен на n векторов.Я не пробовал, но это не должно иметь большого значения.
- Не имеет смысла (на мой взгляд) предоставлять конструкторы копирования для таких прокси (поскольку они, в конце концов, не являются векторами).
- Невозможно (или, по крайней мере, слишком сложно) глобально отсортировать VecProxy, поскольку не все элементы принадлежат одному и тому же контейнеру.