在vector <vector <string>&gt; </vector <string>中查找元素

时间:2014-09-05 10:44:12

标签: c++

我将此文件存储在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.

我想使用findfind_if函数。

3 个答案:

答案 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不会让你在捕获中定义columntarget,如果你想在C ++ 11中避免使用中间变量,你可以这样做,它可以做到这一点只是static_cast的丑陋原因。您只需将"c"1设置为targetcolumn

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;