我将此文件存储在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
函数。
答案 0 :(得分: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;
如果你的内部lambda要在任何位置找到"c"
,我不会在这里使用transform iterator,因为我们想在每个内部向量上返回一个true / false,而不仅仅是一些转换后的值,我们会使用在外部向量上找到find_if并在内部向量上找到
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 :(得分:0)
您可以尝试类似于以下代码的内容
#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
答案 2 :(得分: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;