On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 17.11.18 17:21. Заголовок: -Как найти вектор внутри вектора векторов.


Нередко начинающие программисты, задающие вопросы на сайте Stackoverflow, принимают в качестве лучшего ответа ответ с неправильным решением в силу своей недостаточностью знаний и квалификации.

Пример такого поведения можно найти в следующем заданном вопросе начинающего программиста на Stacloverflow How to find a vector inside a vector

Автор вопроса спрашивает, как найти вектор внутри другого вектора. Очевидно, что вопрос сформулирован некорректно. На самом деле автору нужно найти объект типа struct B внутри вектора типа std::vector<B>, являющегося членом класса struct A.

Критерий поиска объектов типа sstruct B является равенство векторов, объявленных в этих объектах.

Автор признанного лучшим (единственного) ответа решает совершенно другую задачу. Он ищет первых элемент типа struct B в объекте типа struct A, который содержит любое целочисленное значение, содержащееся в векторе, объявленном в объекте типа struct B. С этой целью он использует стандартный алгоритм std::find_first_of.

А как правильно решить поставленную задачу? Имеется два подхода. Первый - это определить оператор равенства для структуры struct B следующим образом

 
bool operator ==( const B &left, const B &right )
{
return left.a == right.a;
}


И тогда можно будет использовать стандартный алгоритм std::find. Например (объявления структур упрощено посредством исключения не используемых полей)

 
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

struct B
{
std::vector<int> a;
};

bool operator ==( const B &left, const B &right )
{
return left.a == right.a;
}

struct A
{
std::vector<B> a;
};

int main()
{
A s;

s.a.push_back( B { { 10, 29 } } );
s.a.push_back( B { { 50, 69 } } );

B b = { { 10, 29 } };

if ( auto it = std::find( std::begin( s.a ), std::end( s.a ), b ); it != std::end( s.a ) )
{
for ( const auto &item : it->a ) std::cout << item << ' ';
std::cout << '\n';
}
else
{
std::cout << "An object of the type B is not found in the vector s.a\n";
}
}
-
Вывод программы на консоль
 
10 29

Второй подход состоит в том, чтобы использовать стандартный алгоритм std::find_if с лямбда-выражением, которое выполняет требуемое сравнение. Например,
 
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

struct B
{
std::vector<int> a;
};

struct A
{
std::vector<B> a;
};

int main()
{
A s;

s.a.push_back( B { { 10, 29 } } );
s.a.push_back( B { { 50, 69 } } );

B b = { { 10, 29 } };

if ( auto it = std::find_if( std::begin( s.a ), std::end( s.a ), [&]( const B &item ) { return item.a == b.a; } ); it != std::end( s.a ) )
{
for ( const auto &item : it->a ) std::cout << item << ' ';
std::cout << '\n';
}
else
{
std::cout << "An object of the type B is not found in the vector s.a\n";
}
}

В этом случае нет необходимости определять оператор равенства объектов типа struct B. Вывод программы на консоль будет таким же, как показано выше
 
10 29


Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 31
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет