Найти элемент в векторе & lt; vector & lt; string & gt; & gt;

Я храню этот файл в vector<vector<string>>:

   1 a aa  # vector of string stored to `vector<vector<string>>`
2 b bb
3 c cc  # c -> index == 2
4 d dd

Код C ++:

vector<vector<string>> myvect =
{{"1","a","aa"},
{"2","b","bb"},
{"3","c","cc"},
{"4","d","dd"}};

Как я могу искать c во втором столбце и получить его индекс (я знаю, что это во втором векторе) — вывод должен быть 2.

Я хочу использовать find или же find_if функция.

1

Решение

Если вы хотите найти второй столбец внутреннего вектора, вы можете использовать transform_iterator и регулярно find,

transform_iterator в boost будет выглядеть примерно так:

std::vector< std::vector< std::string > > v;
auto lambda = [] ( std::vector< std::string > const& v ) { return v[1]; };

auto transform_end = boost::make_transform_iterator ( v.end() );
return std::find( boost::make_transform_iterator( v.begin(), lambda ),
transform_end, "c" ) != transform_end;

Если ваша внутренняя лямбда найти "c" в любой позиции я бы не использовал итератор преобразования здесь, так как мы хотим возвращать true / false для каждого внутреннего вектора, а не только для некоторого преобразованного значения, и мы использовали бы find_if для внешнего вектора и find для внутреннего.

std::string val = "c";
auto lambda = [ const & ]( std::vector< std::string > const& vInner )
{ return std::find( vInner.begin(), vInner.end(), val ) != v.end(); } ;

return std::find_if( v.begin(), v.end(), lambda );
1

Другие решения

Вы можете попробовать что-то похожее на код ниже

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>int main()
{
std::vector<std::vector<std::string>> v =
{
{ "1", "a", "aa" },
{ "2", "b", "bb" },
{ "3", "c", "cc" },
{ "4", "d", "dd" }
};

std::vector<std::string>::iterator second;
std::string s = "c";

auto first = std::find_if( v.begin(), v.end(),
[&]( std::vector<std::string> &v1 )
{
return (( second = std::find( v1.begin(), v1.end(), s ) ) != v1.end() );
} );

if ( first != v.end() )
{
size_t i = std::distance( v.begin(), first );
size_t j = std::distance( v[i].begin(), second );

std::cout << v[i][j] << std::endl;
}

return 0;
}

Выход

c
0

Вы можете сделать это:

int column = 1; // Set this to the column you need to search;
string target( "c" ); // Set this to the value you need to find
auto found = find_if( myvect.begin(), myvect.end(), [=]( vector< string > row ){ return row[column] == target; } );

cout << ( found == myvect.end() ? "not found" : ( *found2 )[column] ) << endl;

C ++ 11 не позволит вам определить column или же target в захвате, если вы хотите избежать промежуточных переменных в C ++ 11, вы можете сделать это, это просто ужасная причина static_cast, Вам просто нужно установить "c" а также 1 к target а также column:

auto found = find_if( myvect.begin(), myvect.end(), bind( equal_to< string >(), "c", bind( static_cast< const string&( vector<string>::* )( size_t ) const >( &vector< string >::operator[] ), placeholders::_1, 1 ) ) );

Я лично предположил бы, что если ваш размер строки всегда один и тот же, то вы положили его в один std::vector как это: vector<string> myvect = { "1", "a", "aa", "2", "b", "bb", "3", "c", "cc", "4", "d", "dd" }; если вы сделаете это, вы можете написать шаблон для поиска, который будет значительно более гибким:

template< typename T, int stride >
T* templateFind( const vector< T >& myvect, const T& target, int column )
{
typedef array< T, stride > rowSize;

rowSize* end = ( rowSize* )( &*( myvect.begin() ) ) + ( myvect.size() / stride );
rowSize* result = find_if( ( rowSize* )( &*( myvect.begin() ) ), end, [&]( rowSize row ){ return row[column] == target; } );

return result == end ? nullptr : ( ( T* )result ) + column;
}

И используйте это так:

string* found = templateFind< string, 3 >( myvect, "c", 1 );

cout << ( found == nullptr ? "not found" : *found ) << endl;
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector