Объединение двух векторов & lt; cv :: String & gt; в OpenCV с использованием C ++ [duplicate]

Внимание: этот ответ предоставляет решение, которое было релевантным в то время , до того, как были введены новые возможности MongoDB 2.2 и выше. См. Другие ответы, если вы используете более новую версию MongoDB.

Параметр селектора полей ограничен полными свойствами. Он не может использоваться для выбора части массива, только для всего массива. Я попытался использовать оператор $ positional , но это не сработало.

Самый простой способ - просто фильтровать фигуры на клиенте.

Если вам действительно нужен правильный вывод непосредственно из MongoDB, вы можете использовать map-reduce для фильтрации фигур.

function map() {
  filteredShapes = [];

  this.shapes.forEach(function (s) {
    if (s.color === "red") {
      filteredShapes.push(s);
    }
  });

  emit(this._id, { shapes: filteredShapes });
}

function reduce(key, values) {
  return values[0];
}

res = db.test.mapReduce(map, reduce, { query: { "shapes.color": "red" } })

db[res.result].find()
147
задан royhowie 24 November 2015 в 10:00
поделиться

7 ответов

AB.reserve( A.size() + B.size() ); // preallocate memory
AB.insert( AB.end(), A.begin(), A.end() );
AB.insert( AB.end(), B.begin(), B.end() );
248
ответ дан Kirill V. Lyadvinsky 21 August 2018 в 23:12
поделиться
  • 1
    Благодаря! Не думал бы о резерве. – jmasterx 5 July 2010 в 05:40
  • 2
    он должен копировать каждый элемент, так что это O (n) – Kirill V. Lyadvinsky 11 March 2013 в 19:40
  • 3
    @boycy Нет. Это амортизированное постоянное время для push_back одного элемента. Чтобы отбросить n элементов, O (n) – Konrad Lindenbach 12 March 2016 в 02:47
  • 4
    @ Konrad Я не подразумевал иначе, но спасибо за разъяснение. Обратите внимание, что сложность операции вставки никогда не задается в терминах количества вставленных элементов, которое всегда будет давать O (n), но в терминах количества элементов уже в контейнере, поскольку что обеспечивает степень масштабируемости. – boycy 14 March 2016 в 11:12
  • 5
    @Prakhar Agrawal AB.insert () будет вставлять новые элементы один за другим, что может привести к неэффективному распределению памяти (последовательность перераспределения памяти). – Kirill V. Lyadvinsky 1 July 2016 в 06:55

Зависит от того, действительно ли вам нужно физически объединить два вектора или вы хотите создать конкатенацию ради итерации. Функция boost :: join

http://www.boost.org/doc/libs/1_43_0/libs/range/doc/html/range/reference/utilities/join.html

даст вам это.

std::vector<int> v0;
v0.push_back(1);
v0.push_back(2);
v0.push_back(3);

std::vector<int> v1;
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
...

BOOST_FOREACH(const int & i, boost::join(v0, v1)){
    cout << i << endl;
}

должен дать вам

1
2
3
4
5
6

Примечание boost :: join не копирует два вектора в новый контейнер, но генерирует пару итераторов (диапазон), которые охватывают промежуток обоих контейнеров. Будет некоторая рабочая нагрузка, но, возможно, меньше, чем копирование всех данных в новый контейнер.

19
ответ дан bradgonesurfing 21 August 2018 в 23:12
поделиться

Если ваши векторы отсортированы *, проверьте set_union из & lt; algorithm & gt;.

set_union(A.begin(), A.end(), B.begin(), B.end(), AB.begin());

В ссылке

есть более подробный пример ] * thanks rlbond

0
ответ дан Cogwheel 21 August 2018 в 23:12
поделиться
  • 1
    set_union работает только на отсортированных диапазонах. – rlbond 5 July 2010 в 05:45
  • 2
    Кроме того, он не делает то же самое, что и прямое добавление - элементы в выходном диапазоне уникальны, что может и не быть тем, чего хочет OP (они могут быть даже не сопоставимы). Это, конечно, не самый эффективный способ сделать это. – Peter 5 July 2010 в 06:13

На основании Ответ Кирил В. Лядвинский , я сделал новую версию. Этот фрагмент использует шаблон и перегружает. С его помощью вы можете писать vector3 = vector1 + vector2 и vector4 += vector3. Надеюсь, это поможет.

template <typename T>
std::vector<T> operator+(const std::vector<T> &A, const std::vector<T> &B)
{
    std::vector<T> AB;
    AB.reserve( A.size() + B.size() );                // preallocate memory
    AB.insert( AB.end(), A.begin(), A.end() );        // add A;
    AB.insert( AB.end(), B.begin(), B.end() );        // add B;
    return AB;
}

template <typename T>
std::vector<T> &operator+=(std::vector<T> &A, const std::vector<T> &B)
{
    A.reserve( A.size() + B.size() );                // preallocate memory without erase original data
    A.insert( A.end(), B.begin(), B.end() );         // add B;
    return A;                                        // here A could be named AB
}
8
ответ дан Community 21 August 2018 в 23:12
поделиться
  • 1
    Вы хотите добавить элементы каждого вектора друг к другу? Или вы хотите добавить? Это ясно сейчас, но в течение следующих 5 лет ..? Вы не должны перегружать оператора, если значение неоднозначно. – S.R 9 August 2017 в 15:31
  • 2
    @ S.R Я хочу сказать. Я написал этот ответ 3 года назад. Я все еще знаю, что это значит. Нет проблем. Если C ++ может обеспечить собственную перегрузку, это будет еще лучше. (и да :: принимается;) – aloisdg 10 August 2017 в 17:36
  • 3
  • 4
  • 5

еще один простой вариант, который не был назван струей:

copy(A.begin(),A.end(),std::back_inserter(AB));
copy(B.begin(),B.end(),std::back_inserter(AB));

и с использованием алгоритма слияния:

#include <algorithm> #include <vector> #include <iterator> #include <iostream> #include <sstream> #include <string> template<template<typename, typename...> class Container, class T> std::string toString(const Container<T>& v) { std::stringstream ss; std::copy(v.begin(), v.end(), std::ostream_iterator<T>(ss, "")); return ss.str(); }; int main() { std::vector<int> A(10); std::vector<int> B(5); //zero filled std::vector<int> AB(15); std::for_each(A.begin(), A.end(), [](int& f)->void { f = rand() % 100; }); std::cout << "before merge: " << toString(A) << "\n"; std::cout << "before merge: " << toString(B) << "\n"; merge(B.begin(),B.end(), begin(A), end(A), AB.begin(), [](int&,int&)->bool {}); std::cout << "after merge: " << toString(AB) << "\n"; return 1; }

2
ответ дан D. Alex 21 August 2018 в 23:12
поделиться

Именно это функция-член std::vector::insert для

std::vector<int> AB = A;
AB.insert(AB.end(), B.begin(), B.end());
43
ответ дан Robbie Morrison 21 August 2018 в 23:12
поделиться
  • 1
    @Nick: Медленно по сравнению с чем? – GManNickG 5 July 2010 в 06:14
  • 2
    Может быть, он проверяет достаточно места на каждой вставке элемента? Использование запаса заранее ускорит его. – RvdK 5 July 2010 в 10:04
  • 3
    @Nick: Я бы не удивился, если бы каждая современная реализация stdlib специализировалась insert на итераторах с произвольным доступом и была зарезервирована вверх. – GManNickG 5 July 2010 в 20:28
  • 4
    @Gman: Это справедливая точка, поскольку мы знаем, что источником является также вектор (где итератор distance имеет сложность O (1)). Тем не менее, гарантии производительности insert - это то, о чем следует помнить, когда вы можете часто делать лучше, планируя заранее. – Nick Bastin 5 July 2010 в 21:38
  • 5
    @RvdK проверка пространства - это всего лишь несколько инструкций: грузоподъемность, сравнение с размером, условный переход; все из которых незначительны для большинства случаев. Поскольку size < capacity в большинстве случаев прогнозирование ветвлений, скорее всего, приведет к тому, что инструкции ветвления без перераспределения будут находиться в конвейере команд, минимизируя задержку, вызванную ветвлением, за исключением низкого количества итераций. Это предполагает хорошую реализацию вектора, плюс конвейер команд процессора и amp; [хороший], но это довольно надежные предположения для современной инструментальной и настольной машин. Не знаю о смартфонах, хотя .. – boycy 24 February 2015 в 15:50

Все решения верны, но мне было проще написать функцию для ее реализации. например:

template <class T1, class T2>
void ContainerInsert(T1 t1, T2 t2)
{
    t1->insert(t1->end(), t2->begin(), t2->end());
}

Таким образом вы можете избежать временного размещения следующим образом:

ContainerInsert(vec, GetSomeVector());
0
ответ дан user3360767 21 August 2018 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: