Как сравнить два вектора
Перейти к содержимому

Как сравнить два вектора

  • автор:

Как сравнить два вектора

Есть два вектора одинакового размера (кратного трем). Есть другой вектор из целых чисел в три раза меньше первых двух.

Нужно взять первые три элемента из обоих векторов и сравнить попарно (первый из первого вектора с первым из второго и т.п.). Если они совпадают, то записать в третий массив единицу. Иначе — ноль. Проделать это для всех триад в векторах.

Эадача просто решается написанием соответствующего цикла. Однако, хочется сделать решить ее одним вызовом типа std::transform(). Возможно ли это?

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

Можно запоминать порядковый номер вызова и предыдущие данные в функторе сравнения, передаваемом в std::transform, но тогда придется делать массив результатов в три раза больше чем нужно, и потом преобразовывать его. Что тоже не очень хорошо.

Похоже, что нужно что-то более гибкое чем std::transform().

Re: Хитрое сравнение векторов

От: ArtDenis
Дата: 06.04.04 03:39
Оценка:

Hello, Tuo_Bellas!
You wrote:

TB> Есть два вектора одинакового размера .

IMHO: цикл — самый оптимальный вариант.

Posted via RSDN NNTP Server 1.8 beta
Re: Хитрое сравнение векторов

От: jazzer Skype: enerjazzer
Дата: 06.04.04 08:35
Оценка:

Здравствуйте, Tuo_Bellas, Вы писали:

T_B>Всем привет!

T_B>Есть два вектора одинакового размера (кратного трем). Есть другой вектор из целых чисел в три раза меньше первых двух.

T_B>Нужно взять первые три элемента из обоих векторов и сравнить попарно (первый из первого вектора с первым из второго и т.п.). Если они совпадают, то записать в третий массив единицу. Иначе — ноль. Проделать это для всех триад в векторах.

T_B>Эадача просто решается написанием соответствующего цикла. Однако, хочется сделать решить ее одним вызовом типа std::transform(). Возможно ли это?

T_B>Первые два вектора получаются из сторонних источников, так что, к сожалению, изменить их на вектора из трехэлемементных структур не получится (разве что скопировать, но это не оптимально, вектора большие).

T_B>Можно запоминать порядковый номер вызова и предыдущие данные в функторе сравнения, передаваемом в std::transform, но тогда придется делать массив результатов в три раза больше чем нужно, и потом преобразовывать его. Что тоже не очень хорошо.

T_B>Похоже, что нужно что-то более гибкое чем std::transform().

T_B>Спасибо.
T_B>Tuo_Bellas.

ты ведь фактически ты хочешь делать операции на одномерном массиве [3N] как на двумерном [3][N]
напиши класс итератора по своему вектору, который бы выдавал тебе тройки, и все будет решаться легко и просто через transform.
За основу итератора можешь взять slice из std::valarray

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got If you always do what you always did

Как сравнить два вектора в R (с примерами)

Вы можете использовать следующий базовый синтаксис для сравнения двух векторов в R:

#check if two vectors are identical identical(vector_1, vector_2) #display items that are in both vectors intersect(vector_1, vector_2) #display items that are only in first vector, but not in second vector setdiff(vector_1, vector_2) 

В следующих примерах показано, как использовать этот синтаксис на практике.

Пример 1. Проверка идентичности двух векторов

В следующем коде показано, как использовать функцию идентичных() для проверки идентичности двух векторов:

#define vectors vector_1  

Два вектора не идентичны, поэтому возвращается значение FALSE .

Пример 2: найти элементы, которые существуют в обоих векторах

В следующем коде показано, как использовать функцию intersect() для отображения элементов, существующих в обоих векторах:

#define vectors vector_1  

Отображаются три элемента, существующие в обоих векторах.

Мы также можем использовать функцию length() , если просто хотим узнать, сколько элементов существует в обоих векторах:

#find how many items exist in both vectors length(intersect(vector_1, vector_2)) [1] 3 

В обоих векторах существует три элемента.

Пример 3: поиск элементов, которые существуют только в одном векторе

В следующем коде показано, как использовать функцию setdiff() для отображения элементов, существующих в первом векторе, но не во втором:

#define vectors vector_1  

В первом векторе существует ровно один элемент, которого нет во втором векторе.

Мы можем поменять местами два вектора, чтобы идентифицировать элементы, которые существуют во втором векторе, но не в первом:

#define vectors vector_1  

Во втором векторе существуют два элемента, которых нет в первом.

Дополнительные ресурсы

В следующих руководствах объясняется, как выполнять другие распространенные задачи в R:

Как сравнить два вектора массивов?

Имеется vector , в нем находятся несколько сотен тысяч массивов. Массивы int* имеют одинаковый размер (пример: ). Необходимо подсчитать количество одинаковых массивов. На ум приходит, что то такое:

for (int i = 0; i < vectorSize; i++) for (int j = i + 1; j < vectorSize; j++) for (int k = 0; k < vectorSize; k++) if (vector[i][k] == vector[j][k]) n++; 

Но так к массиву внутри вектора нельзя обращаться и считать будет долго.
Отслеживать
3,998 5 5 золотых знаков 20 20 серебряных знаков 35 35 бронзовых знаков
задан 18 июл 2014 в 10:58
43 1 1 золотой знак 1 1 серебряный знак 7 7 бронзовых знаков

Я бы сделал вектор хэш-кодов массивов (это 2 вложенных цикла) (а реально, вектор таких структур struct a_signature < uint64_t hash; int *array; >; ), отсортировал его по hash и уже среди одинаковых hash проводил поэлементное сравнение. Кстати, непосредственно сравнение 2-х массивов можно делать функцией memcmp() (см. man 3 memcmp)

18 июл 2014 в 11:49
А почему странный гибрид из C и C++? Почему внешний у вас vector , а внутренний int* ?
18 июл 2014 в 12:47
Получаю массивы int* из функции, которую не я писал и редактировать нет возможности =(
18 июл 2014 в 12:49

@PastoriXx: структура практически ничем не отличается от класса (просто обычно в неё не кладут логику, а пользуются внешними функциями). Для сортировки можно воспользоваться вариантом std::sort с кастомной функцией сравнения (примените лямбду, если компилятор позволяет; примеры по ссылке).

18 июл 2014 в 12:57

непонятно: нужно сравнить два вектора vector или подсчитать количество одинаковых массивов в одном векторе?

Как сравнить два вектора

Для добавления элементов в вектор применяется функция push_back() , в которую передается добавляемый элемент:

#include #include int main() < std::vectornumbers; // пустой вектор numbers.push_back(5); numbers.push_back(3); numbers.push_back(10); for(int n : numbers) cout << n << "\t"; // 5 3 10 std::cout

Векторы являются динамическими структурами в отличие от массивов, где мы скованы его заданым размером. Поэтому мы можем динамически добавлять в вектор новые данные.

Функция emplace_back() выполняет аналогичную задачу - добавляет элемент в конец контейнера:

std::vector numbers< 1, 2, 3, 4, 5 >; numbers.emplace_back(8); // numbers = < 1, 2, 3, 4, 5, 8 >;

Добавление элементов на определенную позицию

Ряд функций позволяет добавлять элементы на определенную позицию.

  • 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
std::vector numbers< 1, 2, 3, 4, 5 >; auto iter = numbers.cbegin(); // константный итератор указывает на первый элемент numbers.emplace(iter + 2, 8); // добавляем после второго элемента numbers = < 1, 2, 8, 3, 4, 5>;
std::vector numbers1< 1, 2, 3, 4, 5 >; auto iter1 = numbers1.cbegin(); // константный итератор указывает на первый элемент numbers1.insert(iter1 + 2, 8); // добавляем после второго элемента //numbers1 = < 1, 2, 8, 3, 4, 5>; std::vector numbers2 < 1, 2, 3, 4, 5 >; auto iter2 = numbers2.cbegin(); // константный итератор указывает на первый элемент numbers2.insert(iter2 + 1, 3, 4); // добавляем после первого элемента три четверки //numbers2 = < 1, 4, 4, 4, 2, 3, 4, 5>; std::vector values < 10, 20, 30, 40, 50 >; std::vector numbers3 < 1, 2, 3, 4, 5 >; auto iter3 = numbers3.cbegin(); // константный итератор указывает на первый элемент // добавляем после первого элемента три первых элемента из вектора values numbers3.insert(iter3 + 1, values.begin(), values.begin() + 3); //numbers3 = < 1, 10, 20, 30, 2, 3, 4, 5>; std::vector numbers4 < 1, 2, 3, 4, 5 >; auto iter4 = numbers4.cend(); // константный итератор указывает на позицию за последним элементом // добавляем в конец вектора numbers4 элементы из списка < 21, 22, 23 >numbers4.insert(iter4, < 21, 22, 23 >); //numbers4 = < 1, 2, 3, 4, 5, 21, 22, 23>;

Удаление элементов

Если необходимо удалить все элементы вектора, то можно использовать функцию clear :

std::vector v < 1,2,3,4 >; v.clear();

Функция pop_back() удаляет последний элемент вектора:

std::vector v < 1,2,3,4 >; v.pop_back(); // v =

Если нужно удалить элемент из середины или начала контейнера, применяется функция std::erase() , которая имеет следующие формы:

  • erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент
  • erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; auto iter = numbers1.cbegin(); // указатель на первый элемент numbers1.erase(iter + 2); // удаляем третий элемент // numbers1 = < 1, 2, 4, 5, 6 >std::vector numbers2 = < 1, 2, 3, 4, 5, 6 >; auto begin = numbers2.cbegin(); // указатель на первый элемент auto end = numbers2.cend(); // указатель на последний элемент numbers2.erase(begin + 2, end - 1); // удаляем с третьего элемента до последнего // numbers2 =

Также начиная со стандарта С++20 в язык была добавлена функция std::erase() . Она не является частью типа vector. В качестве первого параметра она принимает вектор, а в качестве второго - элемент, который надо удалить:

std::vector numbers3 < 1, 2, 3, 1, 5, 6 >; std::erase(numbers3, 1); // numbers3 =

В данном случае удаляем из вектора numbers3 все вхождения числа 1.

Размер вектора

С помощью функции size() можно узнать размер вектора, а с помощью функции empty() проверить, путой ли вектор:

#include #include int main() < std::vectornumbers; if(numbers.empty()) std::cout

С помощью функции resize() можно изменить размер вектора. Эта функция имеет две формы:

  • resize(n) : оставляет в векторе n первых элементов. Если вектор содержит больше элементов, то его размер усекается до n элементов. Если размер вектора меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию
  • resize(n, value) : также оставляет в векторе n первых элементов. Если размер вектора меньше n, то добавляются недостающие элементы со значением value

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; numbers1.resize(4); // оставляем первые четыре элемента - numbers1 = numbers1.resize(6, 8); // numbers1 =

Важно учитывать, что применение функции resize может сделать некорректными все итераторы, указатели и ссылки на элементы.

Изменение элементов вектора

Функция assign() позволяет заменить все элементы вектора определенным набором:

std::vector langs = < "Java", "JavaScript", "C">; langs.assign(4, "C++"); // langs =

В данном случае элементы вектора заменяются набором из четырех строк "C++".

Также можно передать непосредственно набор значений, который заменит значения вектора:

std::vector langs< "Java", "JavaScript", "C">; langs.assign(< "C++", "C#", "C">); // langs =

Еще одна функция - swap() обменивает значения двух контейнеров:

std::vector clangs < "C++", "C#", "Java" >; std::vector ilangs < "JavaScript", "Python", "PHP">; clangs.swap(ilangs); // clangs = < "JavaScript", "Python", "PHP">; for(std::string lang : clangs)

Сравнение векторов

Векторы можно сравнивать - они поддерживают все операции сравнения: , =, ==, !=. Сравнение контейнеров осуществляется на основании сравнения пар элементов на тех же позициях. Векторы равны, если они содержат одинаковые элементы на тех же позициях. Иначе они не равны:

std::vector v1 ; std::vector v2 ; std::vector v3 ; bool v1v2 = v1 == v2; // true bool v1v3 = v1 != v3; // true bool v2v3 = v2 == v3; // false

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *