9
votes

Vecteur de l'initialisation vectorielle

J'ai une période difficile à faire envelopper ma tête autour de la manière d'initialiser un vecteur de vecteurs.

Typef vecteur >>>>>> datacontainer; p>

je veux que cela soit conforme à p> xxx pré>

adressant les éléments n'est pas le problème. Cela devrait être aussi simple que quelque chose comme P>

for 0..1
    for 0..6
        for 0..479
           for 0..30
               dc[i][j][k][l] = 0.0;


0 commentaires

3 Réponses :


2
votes

Vous devrez probablement définir une taille ou une mémoire de réserve

pourriez-vous faire un pour chacun ou une nichée pour cela appellerait xxx

à chaque niveau.


1 commentaires

.Size () vérifie la taille actuelle du vecteur. Vous voulez .Resize ().



21
votes
  • s'il vous plaît N'utilisez pas de vecteurs imbriqués si la taille de votre stockage est connue à l'avance , c'est-à-dire qu'il existe une raison spécifique > Pourquoi par exemple Le premier index doit être de taille 6 et ne changera jamais. Il suffit d'utiliser un tableau uni. Mieux encore, utilisez boost :: Array . De cette façon, vous bénéficiez de tous les avantages d'avoir un tableau uni (économiser d'énormes quantités d'espace lorsque vous allez multidimensionnel) et les avantages d'avoir une réelle instanciation d'objet.

  • S'il vous plaît Ne pas utiliser de vecteurs imbriqués si votre stockage doit être rectangulaire , c'est-à-dire que vous pourriez redimensionner une ou plusieurs des dimensions, mais chaque "rangée" doit avoir la même longueur à un moment donné. Utilisez boost :: multi_array . De cette façon, vous documentez "Ce stockage est rectangulaire", économisez d'énormes quantités d'espace et permet de redimensionner la capacité de redimensionner, d'avoir un objet réel, etc.

    la chose à propos de std :: vecteur est-ce que c'est (a) est censé être redisisable et (b) ne se soucie pas de son contenu dans le moindre, à condition qu'ils soient de le bon type. Cela signifie que si vous avez un vectoriel >> , alors tous les "vecteurs de ligne" doivent conserver leurs propres informations de conservation séparées sur la durée de leur temps - même si vous voulez appliquer qu'ils sont tous de la même longueur. Cela signifie également qu'ils gèrent tous des allocations de mémoire séparées, qui blesse la performance (comportement de cache) et gaspille encore plus d'espace en raison de la façon dont std :: vecteur réaffectés. Boost :: Multi_array est conçu avec l'attente que vous souhaitiez peut-être le redimensionner, mais ne le redimensionnez pas en permanence par des éléments ajoutés (lignes, pour une matrice / faces à 2 dimensions, pour un 3 Array-dimension / etc.) à la fin. std :: vecteur est conçu pour (potentiellement) des gaspilles pour vous assurer que l'opération n'est pas lente. Boost :: Multi_array est conçu pour économiser de l'espace et garder tout ce qui est soigneusement organisé en mémoire.

    qui dit

    oui, Vous devez faire quelque chose avant de pouvoir indexer dans le vecteur. std :: vecteur ne fera pas par magie que les index se présentent dans l'existence parce que vous souhaitez stocker quelque chose là-bas. Cependant, il est facile de traiter:

    Vous pouvez initialiser par défaut - initialiser le vecteur avec la quantité de zéros appropriée d'abord, puis les remplacer, en utilisant le (taille_t n, const t & valeur = T ()) constructeur. C'est-à-dire xxx

    car une "construite par défaut" int comporte la valeur 0.

    Dans votre cas, nous devons spécifier la taille de chaque dimension, en créant des sous-vecteurs qui sont de la taille appropriée et de laisser le constructeur les copier. Cela ressemble à: xxx

    c'est-à-dire, un d1 est construit de la taille 31, utilisé pour initialiser le d2 < / code>, qui est utilisé pour initialiser le d3 , utilisé pour initialiser résultat .

    Il existe d'autres approches, mais elles sont beaucoup maladroit si vous voulez juste qu'un tas de zéros commence. Si vous allez lire l'ensemble du jeu de données à partir d'un fichier, cependant:

    • Vous pouvez utiliser .push_back () pour ajouter un vecteur. Fabriquez un d1 juste avant la boucle la plus intérieure, dans laquelle vous êtes à plusieurs reprises .push_back () pour le remplir. Juste après la boucle, vous .push_back () le résultat sur le d2 que vous avez créé juste avant la prochaine boucle la plus interne, etc.

    • Vous pouvez redimensionner un vecteur à l'avance avec .Resize () , puis l'indice normalement (jusqu'à la quantité que vous avez redimensionnée).


2 commentaires

Construction soignée là-bas. Je vais donner un coup de pouce multi_eloppe. Merci pour la réponse en profondeur.


Dans la nouvelle norme C ++, la fonctionnalité de boost :: Array est fournie par std :: Array dans la bibliothèque standard.



2
votes

Edit: j'avouer que ce code n'est pas élégant. J'aime @karl réponse quelle est la bonne façon d'y aller.

Ce code est compilé et testé. Il imprimait 208320 zéros qui sont attendus (2 * 7 * 480 * 31) xxx


1 commentaires

C'est exactement ce que j'ai réalisé environ 30 secondes après avoir posté. Cela devrait fonctionner, mais Boost Multi_array de Karl semble être un meilleur choix.