0
votes

Obtenir la ligne Vecteur du vecteur 2D en C ++

J'ai un vecteur de vecteur en C ++ défini avec: vecteur > a;

Supposons que A a été rempli de valeurs. Y a-t-il un moyen rapide d'extraire un vecteur de ligne d'un?

Par exemple, A [0] me donnera le premier vecteur de colonne, mais comment puis-je obtenir rapidement le vecteur de première rangée?


5 commentaires

Strictement parler dans votre vecteur > il n'y a pas de vecteur de ligne. Si vous en voulez un, vous devez le construire. Selon ce que vous voulez, vous devriez envisager d'avoir une vue plutôt que de créer un nouveau conteneur


Je suppose que je suis mal compris les choses mais ne serait pas la première rangée?


@C_STOUDENT C'est une question de convention, échanger "rangée" avec "colonne" et la question est toujours la même


Si cela est censé être une matrice, vous ne devriez pas utiliser vecteur > (localité de mémoire, allocations). Regardez Eigen , il a tout ce dont vous avez besoin!


Qu'essayez-vous? Pourquoi est-ce trop lent? De quoi vous avez besoin du vecteur de ligne? J'ai peur sans plus de contexte, vous ne pouvez pas obtenir une meilleure réponse que "Créer un nouveau vecteur et le remplir en boucle sur votre matrice"


3 Réponses :


2
votes

Il n'y a pas de manière "rapide" avec cette structure de données, vous devez parcourir chaque vecteur de colonne et obtenir la valeur de la ligne souhaitée et l'ajouter au vecteur de ligne temporaire. Wether c'est assez rapide pour vous ou pas dépend de ce dont vous avez besoin. Pour que cela soit aussi rapide que possible, assurez-vous d'attribuer une bonne quantité d'espace dans le vecteur de la ligne cible. Il n'a donc pas besoin d'être redimensionné pendant que vous y ajoutez les valeurs.

Une solution simple au problème de performance consiste à utiliser une bibliothèque matricielle existante, telle que Eigen suggérées dans des commentaires.

Si vous avez besoin de le faire vous-même (car c'est une affectation, ou en raison de problèmes de licence, ou autre), vous devez probablement créer votre propre classe "matrice 2D" et masquer les détails de la mise en œuvre. Ensuite, selon vos besoins, vous pouvez utiliser des astuces comme:

  • avoir un "cache" pour les lignes, donc si la même rangée est extraite plusieurs fois, elle peut être récupérée du cache et un nouveau vecteur n'a pas besoin d'être créé
  • Stockez les données comme vecteur de vecteurs de lignes et vecteur de vecteurs de colonne, de sorte que vous puissiez obtenir des lignes ou des colonnes à une heure constante, au coût d'utilisation de plus de mémoire et de modifier deux fois plus coûteux en raison de la duplication des données
  • modifie de manière dynamique la représentation interne en fonction des besoins en courant, de sorte que vous obtenez une utilisation de la mémoire fixe, mais devez payer le coût de traitement lorsque vous devez modifier la représentation interne
  • stockez des données dans le vecteur plat avec la taille des lignes * colonnes et calculez le décalage correct dans votre propre code à partir de la ligne et de la colonne

    Mais il porte une répétition: quelqu'un l'a déjà fait pour vous, essayez donc d'utiliser une bibliothèque existante, si vous le pouvez ...


0 commentaires

0
votes

La réponse est la suivante: Dans votre cas, il n'y a pas d'option simple correspondante que pour les colonnes. Et l'une des raisons est que le vecteur> est un conteneur mal adapté pour des données multidimensionnelles.

Dans la multi-dimension, c'est l'une des décisions de conception importantes: quelle dimension que vous souhaitez accéder plus efficacement et basée sur la réponse que vous pouvez définir votre conteneur (qui pourrait être très spécialisé et complexe).

Par exemple, dans votre cas: il est entièrement à vous d'appeler un [0] une "colonne" ou une "ligne". Il vous suffit de le faire systématiquement (mieux définir une petite interface autour qui rend cette explicite). Mais arrêtez, ne faites pas cela:

Cela vous amène au niveau suivant: Pour les données multidimensionnelles, vous n'utilisez généralement pas de vecteur> (mais ceci est un problème différent). Regardez des solutions intelligentes et efficaces déjà existantes. Dans Ublas https: //www.boost. org / doc / libs / 1_65_1 / libs / numérique / ublas / doc / index.html ou eigen3 https://eigen.tuxfamily.org/dox/

Vous ne pourrez jamais battre ces bibliothèques hautement optimisées.


0 commentaires

1
votes

Il n'y a pas de moyen vraiment rapide de le faire. aussi comme indiqué, je dirais que la Convention est l'inverse, ce qui signifie que A [0] est en réalité la première ligne, plutôt que la première colonne. Même essayer pour obtenir une colonne n'est pas vraiment trivial, car xxx

est un vecteur très possible > A , Mais il n'y a pas de vraie colonne 1 , 2 , 3 ou 4 . Si vous souhaitez appliquer un comportement comme des colonnes de même longueur, la création d'une classe matrice peut être une bonne idée (ou à l'aide d'une bibliothèque).

Vous pouvez écrire une fonction qui rendrait une fonction qui retournerait un vecteur en itérant sur les lignes, stockant la valeur de colonne appropriée. Mais il faudrait faire attention à ce que vous souhaitiez copier ou signalier les valeurs matricielles ( vecteur / vecteur ). Ce n'est pas très rapide car les valeurs ne sont pas à côté de l'autre en mémoire.


2 commentaires

Je ne dirais pas qu'il y a une sorte de "convention" sur des rangées et des colonnes. C'est une décision complètement arbitraire qui est celle qui. Une façon est probablement plus commune , mais ce n'est pas une convention à suivre.


Bon point. Je suppose que je voudrais juste croire que mon chemin est la façon dont tout le monde le fait: d. S'il n'y a pas d'aspect performant impliqué, car quand je l'écris comme un littéral à l'aide de {{} {} {}} sur plusieurs lignes, vous obtenez ce schéma de jolie rangée.