Создать вектор размеров векторов внутри «2d-вектора» (vector <vector <>>)? - PullRequest
1 голос
/ 11 августа 2011

У меня есть вектор векторов, скажем

std::vector< std::vector<int> > my2dArray;

Теперь я хотел бы иметь вектор, который содержит размеры векторов внутри my2dArray. Вручную это будет выглядеть примерно так:

std::vector<int> mySizes;
for (int i = 0; i < my2dArray.size(); i++ )
{
  mySizes.push_back( my2dArray[i].size() );
}

Есть ли более "элегантный" способ сделать это - без ручной записи цикла - с помощью какого-либо алгоритма STL или подобного?

Ответы [ 3 ]

2 голосов
/ 11 августа 2011

C ++ 03:

typedef std::vector<int> IntVec;
std::vector<size_t> sizes(my2dArray.size());
std::transform(my2dArray.begin(), my2dArray.end(), sizes.begin(), 
               std::mem_fun_ref(&IntVec::size));
0 голосов
/ 11 августа 2011

Это работает. Я пытался использовать sizeVec в качестве члена Sizes, но это не сработало, как обсуждалось в этом вопросе.

#include <string>
#include <iostream> 
#include <algorithm>
#include <vector>

class Sizes
{
public:
    Sizes( std::vector<int>& v ) : sizeVec( v ) {}
    void operator() ( std::vector<int>& v ) { 
        sizeVec.push_back( v.size() );  
    }
    std::vector<int>& sizeVec;
};

void outFunc (int i) {
    std::cout << " " << i;
}
int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<std::vector<int>> twodVec;

    std::vector<int> vec;
    vec.push_back( 6 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );
    vec.push_back( 8 );
    twodVec.push_back( vec );
    vec.push_back( 3 );
    twodVec.push_back( vec );

    std::vector<int> sizeVec;
    Sizes sizes(sizeVec);
    std::for_each( twodVec.begin(), twodVec.end(), sizes );
    std::for_each( sizeVec.begin(), sizeVec.end(), outFunc );

    return 0;
}

РЕДАКТИРОВАТЬ : На мой вопрос об этом ответил Оли Чарльзуорт; Вы можете изменить объект на:

class Sizes
{
public:
    void operator() ( std::vector<int>& v ) { 
        sizeVec.push_back( v.size() );  
    }
    std::vector<int> sizeVec;
};

А потом в основном:

Sizes sizes;
sizes = std::for_each( twodVec.begin(), twodVec.end(), sizes );
std::for_each( sizes.sizeVec.begin(), sizes.sizeVec.end(), outFunc );

если вы предпочитаете. Если у вас есть повышение, вы сможете использовать Boost.Ref , чтобы сделать его еще проще.

РЕДАКТИРОВАТЬ 2: изменил функтор для получения вектора по ссылке, а не по значению, как это было предложено Альфом П. Штейнбахом в вопросе, который я задал по этому поводу.

0 голосов
/ 11 августа 2011

О лучшем, что вы получите (требуется C ++ 11)

std::vector<int> mySizes(my2dArray.size());
auto getSize = [](const std::vector<int> & v) { return v.size(); };
std::transform(my2dArray.begin(), my2dArray.end(), mySizes.begin(), getSize);

Это не очень большое улучшение, и если вы не можете использовать лямбды, я не думаю, что дополнительныебеда стоила бы того.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...