2009-07-02 9 views
1

J'essaie simplement d'en savoir plus sur la sémantique stl et de convertir les anciennes boucles en algorithmes, le cas échéant. J'ai du mal à trouver la meilleure façon de transformer cette boucle en un appel à copier. Des idées?en utilisant la copie avec des tableaux multidimensionnels

vector< vector<float> > rvec; 
    const float * r[Max] = ...; 

    // ... 

    for (int ri=0; ri<N; ri++) 
     for (int rj=0; rj<M; rj++) 
     rvec[ri][rj] = r[ri][rj]; 

Répondre

7
rvec.resize(Max); 
for (int i = 0; i < Max; ++i) { 
    rvec[i].resize(M); 
    std::copy(r[i], r[i] + M, rvec[i].begin()); 
} 

Si rvec lui-même et chaque vecteur dans rvec a déjà la bonne taille, alors le redimensionnement n'est pas nécessaire.

+0

en utilisant des itérateurs vectoriels rendrait ceci plus rapide – Partial

+0

^^^^ ce qui n'est pas nécessairement vrai. – ttvd

2

Vous ne savez pas que vous pouvez le faire avec seulement les algorithmes standards et pas foncteurs (et avec ceux-ci, le code est lié à croître de manière significative que ci-dessus).

Vous savez, parfois une boucle simple est tout simplement la meilleure. Les algorithmes de STL sont très bien, mais puisque C++ n'a pas (encore) de fonctions anonymes ou intégrées dans lambdas, prendre un code parfaitement lisible comme vous le montrez ci-dessus et le convertir en algorithmes STL est plus un exercice intellectuel qu'une amélioration réelle,

+0

Convenu. Lancer des itérateurs partout juste pour utiliser la copie de STL() ne vaut pas la peine de gonfler le code que vous avez déjà qui fait le travail tout aussi bien. –

+1

Les Lambda anonymes font partie du standard C++ 0x, dont une grande partie est déjà supportée par les compilateurs actuels. Cela peut valoir la peine de voir si l'on travaille. – SingleNegationElimination

+0

+1. Pour la plupart des codes, la lisibilité (= maintenabilité) l'emporte sur d'autres préoccupations. OK, si vous vous trouvez faire beaucoup de cela, pensez à créer votre propre modèle de fonction de copie 2D (ou n-D) (). –

1

Dans ce cas, il ne suffit pas de laisser le code tel quel. Bien que si vous l'écriviez plusieurs fois, l'abstraire dans une fonction séparée serait une bonne idée. Un autre point à considérer, toute solution qui ne réserve pas ou redimensionner perdra du temps à copier où vous n'avez pas besoin.

+0

+1. Bon point à propos de reserve()/resize() - cela fera une différence de performance notable si elle est utilisée sur de grands tableaux ou dans des boucles serrées. (C'est-à-dire que ce n'est probablement pas une optimisation prématurée pour envisager de faire ces choses. –

0

Voici un exemple que je fait un peu rapidement avec itérateurs ...

#include <algorithm> 
using std::copy; 
using std::for_each; 
using std::random_shuffle; 

#include <iostream> 
using std::cout; 
using std::endl; 

#include <vector> 
using std::iterator; 
using std::vector; 

void Write(int i) 
{ 
    cout << i << endl; 
} 

int main() 
{ 
    const short MAX_LIST = 1000, 
       MAX_NUMBER = 100; 
    float number = 0; 
    vector<vector<float> > v (MAX_LIST), 
          v2 (MAX_LIST); 
    vector<float> list(MAX_NUMBER); 

    //Fills list and fills v with list 
    for(vector<vector<float> >::iterator v_iter = v.begin(); v_iter != v.end(); ++v_iter) 
    { 
     for(vector<float>::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter) 
     { 
      *list_iter = number; 
      ++number; 
     } 
     *v_iter = list; 
    } 

    //write v to console 
    for(vector<vector<float> >::iterator v_iter = v.begin(); v_iter != v.end(); ++v_iter) 
    { 
     for_each(v_iter->begin(), v_iter->end(), Write); 
    } 

    //copy v to v2 
    cout << "Copying..." << endl; 
    copy(v.begin(), v.end(), v2.begin()); 
    cout << "Finished copying!" << endl; 

    cout<< "Shuffling..." << endl; 
    random_shuffle(v2.begin(), v2.end()); 
    cout << "Finished shuffling!" << endl; 

    //write v2 to console 
    for(vector<vector<float> >::iterator v_iter = v2.begin(); v_iter != v2.end(); ++v_iter) 
    { 
     for_each(v_iter->begin(), v_iter->end(), Write); 
    } 
} 
+0

Vous étiez très explicite sur vos dépendances, mais en utilisant std :: iterator; peut échouer si vous n'incluez pas # . Au lieu de Write avez-vous vu std :: ostream_iterator? –

+0

Si je ne me trompe pas, le vecteur inclut déjà l'itérateur et j'utilise un itérateur vectoriel. Par conséquent, je crois que cela ne devrait pas échouer. D'un autre côté, utiliser std :: ostream_iterator pourrait être une excellente option au lieu de Write! – Partial

+0

Cela ne répond pas à la question. L'OP essayait de copier d'un tableau 2D vers un vecteur 2D. Votre seul appel à std :: copy copie un vecteur 2D dans un autre vecteur 2D. Il montre l'utilisation d'algorithmes standard, mais cela n'aide pas beaucoup. –

Questions connexes