Как сравнить два вектора
Для добавления элементов в вектор применяется функция push_back() , в которую передается добавляемый элемент:
Векторы являются динамическими структурами в отличие от массивов, где мы скованы его заданым размером. Поэтому мы можем динамически добавлять в вектор новые данные.
Функция emplace_back() выполняет аналогичную задачу — добавляет элемент в конец контейнера:
Добавление элементов на определенную позицию
Ряд функций позволяет добавлять элементы на определенную позицию.
emplace(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos
insert(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos, аналогично функции emplace
insert(pos, n, value) : вставляет n элементов value начиная с позиции, на которую указывает итератор pos
insert(pos, begin, end) : вставляет начиная с позиции, на которую указывает итератор pos, элементы из другого контейнера из диапазона между итераторами begin и end
insert(pos, values) : вставляет список значений начиная с позиции, на которую указывает итератор pos
Удаление элементов
Если необходимо удалить все элементы вектора, то можно использовать функцию clear :
Функция pop_back() удаляет последний элемент вектора:
Если нужно удалить элемент из середины или начала контейнера, применяется функция std::erase() , которая имеет следующие формы:
erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент
erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент
Также начиная со стандарта С++20 в язык была добавлена функция std::erase() . Она не является частью типа vector. В качестве первого параметра она принимает вектор, а в качестве второго — элемент, который надо удалить:
В данном случае удаляем из вектора numbers3 все вхождения числа 1.
Размер вектора
С помощью функции size() можно узнать размер вектора, а с помощью функции empty() проверить, путой ли вектор:
С помощью функции resize() можно изменить размер вектора. Эта функция имеет две формы:
resize(n) : оставляет в векторе n первых элементов. Если вектор содержит больше элементов, то его размер усекается до n элементов. Если размер вектора меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию
resize(n, value) : также оставляет в векторе n первых элементов. Если размер вектора меньше n, то добавляются недостающие элементы со значением value
Важно учитывать, что применение функции resize может сделать некорректными все итераторы, указатели и ссылки на элементы.
Изменение элементов вектора
Функция assign() позволяет заменить все элементы вектора определенным набором:
В данном случае элементы вектора заменяются набором из четырех строк «C++».
Также можно передать непосредственно набор значений, который заменит значения вектора:
Еще одна функция — swap() обменивает значения двух контейнеров:
Сравнение векторов
Векторы можно сравнивать — они поддерживают все операции сравнения: <, >, <=, >=, ==, !=. Сравнение контейнеров осуществляется на основании сравнения пар элементов на тех же позициях. Векторы равны, если они содержат одинаковые элементы на тех же позициях. Иначе они не равны:
Compare two vectors C++
I was wondering is there any function to compare 2 string vectors to return the number of different(or the same) elements? Or i have to iterate over both of them and test item by item.
Thanks.
4 Answers 4
Or, if you don’t want to sort:
You may want to use a multiset if there could be duplicates in a vector.
I don’t know of an existing function but writing one yourself shouldn’t be too much trouble.
- Omitted std:: prefix for brevity
- This function needs to be updated if it should handle vector<string> instances of different lengths
Have a look at set_difference() and set_intersection(). In both cases you need to have your containers sorted beforehand.
The content will be compared from both vectors as per the below link documentation:
Compares the contents of two vectors.
1-2) Checks if the contents of lhs and rhs are equal, that is, they have the same number of elements and each element in lhs compares equal with the element in rhs at the same position.
Проверьте, равны ли два вектора или нет в C++
Два вектора называются равными, если они имеют одинаковое содержимое в одном и том же порядке. Если два вектора имеют одинаковое содержимое, но в разном порядке, они не равны друг другу в результате [] оператор меняется. Есть много способов проверить два вектора на равенство в C++, которые обсуждаются ниже. Чтобы проверить, содержат ли два вектора одинаковое содержимое, но в другом порядке, отсортируйте оба вектора перед вызовом любого из следующих методов.
1. Использование == оператор
Самое простое решение — использовать == оператор, который проверяет, равно содержимое двух контейнеров или нет.
Сравнение векторов в с
Всем привет! До этого дня мы использовали чистые массивы. Чистые — это значит простые массивы, не имеющие у себя в багаже различных функций. В этом уроке мы пройдем нечистые массивы — векторы.
Быстрый переход по статье:
Что такое вектор (vector)
Вектор — это структура данных, которая уже является моделью динамического массива.
Давайте вспомним о том, что для создания динамического массива (вручную) нам нужно пользоваться конструктором new и вдобавок указателями. Но в случае с векторами всего этого делать не нужно.
Вообще, по стандарту пользоваться динамическим массивом через конструктор new — не есть правильно. Так как в компьютере могут происходить различные утечки памяти.
Как создать вектор (vector) в C++
Сначала для создания вектора нам понадобится подключить библиотеку — , в ней хранится шаблон вектора.
Кстати, сейчас и в будущем мы будем использовать именно шаблон вектора. Например, очередь или стек, не созданные с помощью массива или вектора, тоже являются шаблонными.
Далее, чтобы объявить вектор, нужно пользоваться конструкцией ниже:
- Вначале пишем слово vector .
- Далее в угольных скобках указываем тип, которым будем заполнять ячейки.
- И в самом конце указываем имя вектора.
В примере выше мы создали вектор строк.
Кстати, заполнить вектор можно еще при инициализации (другие способы мы пройдем позже — в методах вектора). Делается это также просто, как и в массивах. Вот так:
После имени вектора ставим знак равенства и скобки, в которых через пробел указываем значение элементов.
Такой способ инициализации можно использовать только в C++!
Так, чтобы заполнить вектор строками, нам нужно использовать кавычки — «строка» .
Второй способ обратиться к ячейке
Мы знаем, что в векторе для обращения к ячейке используются индексы. Обычно мы их используем совместно с квадратными скобками [] .
Но в C++ есть еще один способ это сделать благодаря функции — at(). В скобках мы должны указать индекс той ячейки, к которой нужно обратиться.
Вот как она работает на практике:
Давайте запустим эту программу:
Как указать количество ячеек для вектора
Указывать размер вектора можно по-разному. Можно это сделать еще при его инициализации, а можно хоть в самом конце программы. Вот, например, способ указать длину вектора на старте:
Так в круглых скобках () после имени вектора указываем первоначальную длину. А вот второй способ:
Первая строчка нам уже знакома. А вот во второй присутствует незнакомое слово — reserve , это функция, с помощью которой мы говорим компилятору, какое количество ячеек нам нужно использовать.
Вы можете задать логичный вопрос:»А в чем разница?». Давайте создадим два вектора и по-разному укажем их количество ячеек.
Как видим, в первом случае мы вывели три нуля, а во втором: 17, 0, 0.
Все потому, что при использовании первого способа все ячейки автоматически заполнились нулями.
При объявлении чего-либо (массива, вектора, переменной и т.д) мы выделяем определенное количество ячеек памяти, в которых уже хранится ненужный для ПК мусор. В нашем случае этим мусором являются числа.
Поэтому, когда мы вывели второй вектор, в нем уже находились какие-то рандомные числа — 17, 0, 0. Обычно они намного больше. Можете кстати попробовать создать переменную и вывести ее значение.
Нужно помнить! При использовании второго способа есть некоторый плюс — по времени. Так как для первого способа компилятор тратит время, чтобы заполнить все ячейки нулями.
Как сравнить два вектора
Если в середине программы нам понадобиться сравнить два массива, мы, конечно, используем цикл for и поочередно проверим все элементы.
Вектор снова на шаг впереди! Чтобы нам сравнить два вектора, потребуется применить всего лишь оператор ветвления if.
C++: сравнение двух векторов
есть ли способ сравнить два вектора?
Примечание: в настоящее время, эти векторы не отсортированы и содержат целые значения.
4 ответов
Регистрация std::mismatch метод C++.
сравнение векторов обсуждалось на форум DaniWeb и ответил.
Проверьте ниже Сообщение SO. будет полезно для вас. они добились того же с помощью метода different-2.
ваш код ( vector1 == vector2 ) — правильный синтаксис C++. Есть == оператора для векторов.
если вы хотите сравнить короткий вектор с частью более длинного вектора, вы можете использовать equal() оператора для векторов. (документации)
если они действительно абсолютно должны оставаться несортированными (чего они действительно не делают.. и если вы имеете дело с сотнями тысяч элементов, я должен спросить, почему вы сравниваете векторы, подобные этому), вы можете взломать метод сравнения, который работает с несортированными массивами.
единственный способ сделать это-создать временный vector3 и притворись, что делаешь set_intersection путем добавления всех элементов vector1 к нему, затем выполните поиск для каждого отдельного элемента vector2 на vector3 и удаление его, если найдено. Я знаю, что это звучит ужасно, но именно поэтому я не пишу никаких стандартных библиотек C++ в ближайшее время.
на самом деле, просто сначала отсортируйте их.
C ++ 11 — Как эффективно сравнить векторы с C ++?
Мне нужен совет для микрооптимизации в C ++ для функции сравнения векторов,
он сравнивает два вектора на равенство и порядок элементов не имеет значения.
Эта функция интенсивно используется, и я думаю о возможном способе ее оптимизации.
Можете ли вы дать мне несколько предложений? Кстати я использую C ++ 11.
Решение
Он только что понял, что этот код выполняет только своего рода проверку «эквивалентности набора» (и теперь я вижу, что вы на самом деле говорили это, какой я паршивый читатель!). Это может быть достигнуто гораздо проще
Вам нужно будет включить заголовок algorithm ,
Если ваши векторы всегда имеют одинаковый размер, вы можете добавить утверждение в начале метода:
Это будет удобно при отладке вашей программы, если вы однажды выполните эту операцию для неравной длины по ошибке.
В противном случае векторы не могут быть одинаковыми, если они имеют неодинаковую длину, поэтому просто добавьте
до инструкции сортировки. Это сэкономит вам много времени.
Сложность этого технически O(n*log(n)) потому что это в основном зависит от сортировки, которая (как правило) имеет такую сложность. Это лучше чем твой O(n^2) подход, но может быть и хуже из-за необходимых копий. Это не имеет значения, если ваши оригинальные векторы могут быть отсортированы.
Если вы хотите придерживаться своего подхода, но настроить его, вот мои мысли по этому поводу:
Ты можешь использовать std::find за это:
Другая возможность — замена структуры для хранения свободных позиций. Вы можете попробовать std::bitset или просто сохраните используемые индексы в векторе и проверьте, нет ли совпадения в этом индексе-векторе. Если результат этой функции очень часто один и тот же (то есть либо в основном истинный, либо в основном ложный), вы можете оптимизировать свои структуры данных, чтобы отразить это. Например. Я бы использовал список использованных индексов, если результат, как правило, ложный, поскольку может понадобиться сохранить только несколько индексов.
Этот метод имеет ту же сложность, что и ваш подход. Использование std :: find для поиска вещей иногда лучше, чем ручной поиск. (Например, если данные отсортированы и компилятор знает об этом, это может быть двоичный поиск).
Другие решения
Ваша банка вероятностно Сравните два несортированных вектора (u, v) в O (n):
Если U == V, то векторы, вероятно, равны.
ч (х) — это любой некриптографическая хеш-функция — такие как MurmurHash. (Криптографические функции также будут работать, но обычно будут медленнее).
(Это будет работать даже без хэширования, но будет гораздо менее надежным, когда значения имеют относительно небольшой диапазон).
128-битная хеш-функция была бы достаточной для многих практических применений.
Я заметил, что большинство предлагаемых решений включало сортировку входных векторов. Я думаю, что сортировка массивов вычисляет больше, чем то, что строго необходимо для оценки равенства двух векторов (и, если входные векторы постоянны, копия должна быть сделал).
Другим способом было бы создать ассоциативный контейнер для подсчета элемента в каждом векторе … Также возможно сделать сокращение двух векторов параллельно. В случае очень большого вектора, который может дать хорошее ускорение.
Таким образом, в зависимости от производительности вашей функции хеширования, мы можем получить линейную сложность длины вектора кабины (против n * logn с сортировкой).
NB код может иметь какую-то ошибку, успел проверить это …
Сравнительный анализ этого способа сравнения двух векторов с сортировкой на основе ubuntu 13.10, vmware core i7 gen 3:
Сравнение 200 векторов из 500 элементов путем подсчета занимает 0,184113 секунды.
Сравнение 200 векторов из 500 элементов путем сортировки занимает 0,276409 секунд.
Сравнение 200 векторов из 1000 элементов путем подсчета занимает 0,359848 секунд.
Сравнение 200 векторов из 1000 элементов путем сортировки занимает 0,559436 секунд.
Сравнение 200 векторов из 5000 элементов путем подсчета занимает 1.78584 секунды.
Сравнение 200 векторов из 5000 элементов путем сортировки занимает 2,997983 секунды.
Как и предполагали другие, предварительная сортировка векторов повысит производительность.
В качестве дополнительной оптимизации вы можете сделать кучу из векторов для сравнения (со сложностью O (n) вместо сортировки с O (n * log (n)).
После этого вы можете извлекать элементы из обеих куч (сложность O (log (n))), пока не получите несоответствие.
Преимущество этого состоит в том, что вы сортируете свои векторы, а не сортируете их, если они не равны.
Ниже приведен пример кода. Чтобы узнать, что на самом деле быстрее, вам придется сравнить некоторые примеры данных для вашего варианта использования.
Если вы часто используете эту функцию для одних и тех же векторов, может быть лучше сохранить отсортированные копии для сравнения.
Теоретически, может быть даже лучше отсортировать векторы и сравнить отсортированные векторы, если каждый из них сравнивается только один раз (сортировка — это O (n * log (n)), сравнивая отсортированный вектор O (n), а ваша функция — O ( п ^ 2).
Но я полагаю, что время, потраченное на выделение памяти для отсортированных векторов, превзойдет любые теоретические выгоды, если вы не будете часто сравнивать одни и те же векторы.
Как и во всех оптимизациях, профилирование — единственный способ убедиться, что я попробую std::sort / std::equal комбо.
Как Стефан говорит, что вам нужно сортировать, чтобы получить лучшую сложность.
Тогда вы можете использовать
== оператор (tnx для исправления в комментариях — ste равный также будет работать, но он больше подходит для сравнения диапазонов, а не целых контейнеров)
Если это не достаточно быстро только тогда, заняться микрооптимизацией.
Также гарантированно, что векторы имеют одинаковый размер?
Если не поставить эту проверку в начале.
Другое возможное решение (жизнеспособное, только если все элементы уникальны), которое должно несколько улучшить решение @stefan (хотя сложность осталась бы в O (NlogN)):
Это должно быть быстрее, так как он выполняет поиск непосредственно как O(NlogN) операция, а не сортировка b ( O(NlogN) ) и затем поиск обоих векторов ( O(N) ).