Trouver max/min de vecteur de vecteurs
Ce qui est le plus efficace et le standard C++11/14) pour trouver la valeur max/min élément de vecteur de vecteurs?
std::vector<std::vector<double>> some_values{{5,0,8},{3,1,9}};
le voulait max élément est 9
le voulait min élément est 0
std::minmax_element
pour l'intérieur des vecteurs.- Pourquoi ne pas utiliser 2 boucles imbriquées? Les autres moyens sont peut-être moins lisible.
- Tu veux dire passer throgh chaque intérieur vecteur et appel minmax_elemnt et ensuite trouver le minmax_elemnt du résultat ?
- c'est une solution. Mais je me demandais si il y a une mst fonction ou un motif pour cela.
- Il suffit d'aller plus chaque vecteur et de créer deux variables min et max et de les comparer
- oui, c'est la dernière option pour moi. Je cherchais quelque chose de plus clair
- Pour la boucle externe, il semble plus compliqué à utiliser directement l'algorithme standard.
- Je vois... BTW, n'est pas possible de bénéficier de la continuité de la propriété de stocker vecteur pour convertir de le traiter comme une seule dimension ?
- un vecteur de vecteurs n'est pas stockés de manière contiguë, de chaque intérieur vecteur est stockée dans son propre bloc contigu de mémoire allouée dynamiquement, donc vous ne pouvez pas vraiment les traiter comme des "unidimensionnel". Vous pouvez changer la façon dont vous stockez votre tableau 2D tel qu'il est stocké de manière contiguë, alors vous pourriez être en mesure de simplifier la mise en œuvre un peu.
- vous devez préciser votre question - soit un texte ou d'un exemple - pour le rendre clair, vous êtes à la recherche pour le min et le max
double
valeur, et non pas le min et le maxvector<double>
, étant donnéelement
est ambigu (l'extérieur du vecteur des éléments à l'intérieur des vecteurs). - il a été fait
Vous devez vous connecter pour publier un commentaire.
Tout moyen efficace pour calculer le maximum d'élément dans un tableau 2d(ou un vecteur dans votre cas) implique une complexité de
O(n^2)
indépendamment de ce que vous faites, comme le calcul implique une comparaison entren*n
éléments.Meilleure façon en termes de facilité d'utilisation est l'utilisation destd::max_element
sur le vecteur de vecteurs.Je ne vais pas entrer dans les détails.Voici la de référence.O(nlog(n)
. Juste pour l'insertion des valeurs.O(N)
oùN
est le nombre total d'éléments à comparer. Le fait que ce soit physiquement commeK
vecteurs de la moyenneN/K
sous-éléments est un peu trompeur.O(n)
. Je ne sais pas pourquoi les gens disent quadratique.n^2
éléments pour arriver à la bonne réponse.Peu importe ce que vous faites la complexité n'est pas réductible au-delà.Ses comme le fameux nombre minimum de courses pour trouver le cheval le plus rapide du problème.std::min_element
est en termes de nombre d'appels àoperator<
par rapport au nombre total d'élémentsN
. Le fait qu'ils sont divisés en plusieurs bacs n'a pas d'importance, sauf pour l'écriture de boucles imbriquées, mais l'imbrication n'est pas un "round-robin" tournoi de comparer chaque élément avec tous les autres éléments. Chaque élément est uniquement par rapport à la min jusqu'à présent. Pour 100 numéros, vous avez 99 comparaisons. Pour un 1000, vous avez 999. C'estO(N)
.O(n)
. même si vous essayez de modifier les données que vous avez besoin d'accéder àm*n
éléments n'est-ce pas ?std::min_element
est défini comme le nombre de comparaisons par rapport au nombre total d'éléments. Il a été expliqué à plusieurs reprises que la mise en page dans le vecteur de vecteur est sans importance ici. Donc downvoted jusqu'fixe.m*n
.stackoverflow.com/questions/11032015/...O(n)
pour quelles que soient les valeurs der
etc
oùr*c = n
. Personnellement, les rapports de la complexité en O(n^2) est trompeuse. Je comprends ce que tu veux bien. Je pense juste qu'il va embrouiller les gens en disant que c'est quadratique juste parce que vous avez besoin d'une boucle imbriquée.n*n
. Jetez un oeil à la deuxième solution ici stackoverflow.com/questions/21637241/.... D'abord on n'est pas pertinente car elle manipule l'entrée.Voici un multi-fileté solution qui renvoie un itérateur (ou lance) au maximum pour général type de
T
(en supposant queoperator<
est défini pourT
). Remarque la plus importante de l'optimisation est à effectuer à l'intérieur max opérations sur les "colonnes" à exploiter C++de classement de la colonne principale.threaded_transform
ne fait pas partie de la bibliothèque standard (encore), mais voici une application que vous pouvez utiliser.Si vous avez utilisé un
boost::multi_array<double, 2>
au lieu d'unstd::vector<std::vector<double>>
il serait aussi simple que:Démonstration en direct.
Vous devez au moins rechercher à chaque élément, de sorte que, comme l'Anony-souris mentionné, la complexité sera au moins O(n^2).
Si vous créer un itérateur pour parcourir tous
double
de votrevector
devector
, une simplestd::minmax_element
faire le travailitérateur est quelque chose comme:
Et l'utilisation peut être
Live exemple
La plaine
for loop
façon:À l'aide de la
s'accumuler
fonction, vous pouvez écrire:mais je préfère la bonne, vieille de boucle.
L'exemple peut être étendu à trouver à la fois les valeurs min et max:
Malheureusement un vecteur de vecteur n'est pas stockés de manière contiguë en mémoire, de sorte que vous n'avez pas un seul bloc contenant toutes les valeurs (c'est une des raisons pour lesquelles un vecteur de vecteur n'est pas un bon modèle pour une matrice).
Vous pouvez profiter d'un vecteur de vecteur si elle contient beaucoup d'éléments.
Puisque chaque sous-vecteur est autonome, vous pouvez utiliser std::async à remplir de manière asynchrone un vecteur de contrats à terme contenant la valeur max de chaque sous-vecteur.
Vous pouvez le faire assez facilement avec Eric Niebler de gamme-v3 de la bibliothèque (qui, évidemment, n'est pas standard, mais nous espérons être dans le pas trop lointain avenir):
p.first
est un itérateur à la min élément;p.second
au max.(gamme-v3 ne de mise en œuvre de minmax_element, mais malheureusement, il nécessite un ForwardRange et vue::joignez-vous seulement me donne une InputRange, donc je ne peux pas l'utiliser).
La méthode la plus simple serait d'abord une fonction pour déterminer la valeur max/min des éléments d'un vecteur, dire une fonction appelée:
Le passage par référence (lecture seulement) dans ce cas, ils seront beaucoup plus de temps et plus efficace de l'espace (vous ne voulez pas que votre fonction copier l'intégralité d'un vecteur). Ainsi, dans votre fonction pour déterminer le max/min élément d'un vecteur de vecteurs, vous auriez une boucle imbriquée, tels que:
Le problème avec la solution ci-dessus est son inefficacité. De ma connaissance, cet algorithme est généralement exécuté sur O(n^2log(n)) l'efficacité, ce qui est assez exceptionnel. Mais bien sûr, il est toujours une solution. Bien qu'il pourrait y avoir des algorithmes standard qui peut trouver le max/min de un vecteur pour vous, c'est toujours plus de l'accomplissement de l'écriture de vos propres, et à l'aide de la donner, l'habitude de ne rien en termes d'amélioration de l'efficacité, car l'algorithme sera généralement le même (pour les petites fonctions qui déterminent max/min). En fait, théoriquement, fonctions standard irait un peu moins rapide puisque ces fonctions sont des modèles qui ont à déterminer le type il s'agit, au moment de l'exécution.
Permet de dire que nous avons un vecteur nommé some_values, comme indiqué ci-dessous
définir une dimension de vecteur comme indiqué ci-dessous
Puis de trouver un maximum/minimum élément unidimensionnel vecteur comme indiqué ci-dessous
Maintenant, vous obtenez la valeur max/min des éléments ci-dessous
ou optimazed variante: