Я храню этот файл в 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
функция.
Если вы хотите найти второй столбец внутреннего вектора, вы можете использовать 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 );
Вы можете попробовать что-то похожее на код ниже
#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
Вы можете сделать это:
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;