Quelle est la meilleure façon d'obtenir la valeur minimale ou maximale d'un Tableau de nombres?
Disons que j'ai un Tableau de nombres: [2,3,3,4,2,2,5,6,7,2]
Quelle est la meilleure façon de trouver la valeur minimale ou maximale dans ce Tableau?
Droit maintenant, pour obtenir le maximum, je suis en boucle à travers la Matrice, et la réinitialisation d'une variable à la valeur que si elle est supérieure à la valeur existante:
var myArray:Array /* of Number */ = [2,3,3,4,2,2,5,6,7,2];
var maxValue:Number = 0;
for each (var num:Number in myArray)
{
if (num > maxValue)
maxValue = num;
}
Cela ne semble pas comme la meilleure façon de le faire (j'essaie d'éviter les boucles, si possible).
- L'exécution d'un foreach sur de simples tableaux comme ce n'est jamais un goulot d'étranglement. Le seul moment où les boucles sont cher, c'est quand vous faites quelque chose de mauvais comme d'exécuter du SQL à l'intérieur d'une boucle ou dupliquer une sorte de calcul qui sera toujours le même à chaque fois. N'a pas peur de la boucle de mon ami!
- Quel est le problème avec les boucles?
- Ce que vous devez essayer de les éviter sont profondément imbriqués de boucles...
Vous devez vous connecter pour publier un commentaire.
Les réponses théoriques à partir de tout le monde sont tous propres, mais soyons pragmatiques. ActionScript fournit les outils dont vous avez besoin, de sorte que vous n'avez même pas à écrire une boucle dans ce cas!
Tout d'abord, notez que
Math.min()
etMath.max()
peut prendre un nombre quelconque d'arguments. Aussi, il est important de comprendre laapply()
méthode disponible pourFunction
objets. Il vous permet de passer des arguments à la fonction à l'aide d'unArray
. Prenons l'avantage de deux:Voici la meilleure partie: la "boucle" est en fait exécuter à l'aide de code natif (à l'intérieur de Flash Player), de sorte qu'il est plus rapide que de chercher la valeur minimale ou maximale à l'aide d'un pur ActionScript boucle.
apply
est connu médiocres par rapport à la normale de l'appel de fonction.Il n'existe pas de moyen fiable pour obtenir le nombre minimal/maximal sans vérification de chaque valeur. Vous ne voulez pas essayer un sort ou quelque chose comme ça, en marchant à travers la matrice est en O(n), ce qui est mieux que n'importe quel algorithme de tri peut le faire dans le cas général.
Si
Alors il existe un algorithme qui trouve le min et le max 3n/2 nombre de comparaisons. Ce qu'on doit faire est de traiter les éléments de la matrice dans les paires. La plus grande, la paire devrait être comparé avec le courant max et la plus petite de la paire doit être comparé avec le courant min. Aussi, il faut prendre des précautions particulières si le tableau contient un nombre impair d'éléments.
Dans du code c++ (emprunt du code de Mehrdad).
Il est très facile de voir que le nombre de comparaisons qu'il prend est 3n/2. La boucle s'exécute n/2 fois et à chaque itération 3 les comparaisons sont effectuées. C'est probablement l'optimum l'on peut obtenir. En ce moment, je ne peut pas pointer vers une source précise de qui. (Mais, je crois avoir vu une preuve de quelque part.)
La solution récursive donné par Mehrdad ci-dessus, probablement réalise également le faible nombre de comparaisons (la dernière ligne doit être changé). Mais avec le même nombre de comparaisons itératif toujours la solution de battre une solution récursive en raison de la surcharge dans l'appel de fonction comme il l'a mentionné. Cependant, si l'on ne se soucie de trouver des min et max de quelques chiffres (comme Eric Belair, t), personne ne remarquerez aucune différence dans notre ordinateur avec l'une des méthodes ci-dessus. Pour un grand tableau, la différence pourrait être importante.
Bien que cette solution, et la solution donnée par Matthieu Brubaker a O(n) la complexité, dans la pratique, on doit soigneusement évaluer les constantes cachées impliqués. Le nombre de comparaisons dans sa solution est 2n. L'accélération acquise avec la solution 3n/2 comparaisons, par opposition à 2n comparaisons serait notable.
À moins que le tableau est trié, c'est le meilleur que vous allez obtenir. Si elle est triée, il suffit de prendre le premier et le dernier éléments.
Bien sûr, si ce n'est pas triée, puis trier d'abord et saisissant la première et la dernière est la garantie d'être moins efficace que de simplement en parcourant une fois. Même les meilleurs algorithmes de tri ont à examiner chaque élément de plus d'une fois (une moyenne de O(log N) fois pour chaque élément. C'est O(N*Log N) total. Un simple scan une fois n'est O(N).
Si vous êtes désireux d'accès rapide pour le plus grand élément dans une structure de données, jetez un oeil à des tas pour un moyen efficace de garder des objets dans un certain ordre.
Que vous avez à parcourir le tableau, pas d'autre moyen de vérifier tous les éléments. Juste une correction pour le code - si tous les éléments sont négatifs, maxValue sera de 0 à la fin. Vous devez l'initialiser avec la valeur minimum possible pour entier.
Et si vous allez à la recherche de la matrice de nombreuses fois, c'est une bonne idée de les trier d'abord, que la recherche est plus rapide (binaire de recherche) et le minimum et le maximum des éléments sont juste la première et la dernière.
Dépend de ce que vous appelez "le mieux". À partir d'un point de vue théorique, vous ne pouvez pas résoudre le problème en moins de
O(n)
dans une machine de Turing déterministe.Les naïfs algorithme est trop de la boucle et mettre à jour min, max. Toutefois, une solution récursive nécessitera moins de comparaisons que naïfs algorithme, si vous voulez obtenir min, max en même temps (il n'est pas nécessairement plus rapide en raison de l'appel de fonction à la verticale).
La solution la plus simple serait de trier et d'obtenir le premier et le dernier élément, si ce n'est évidemment pas le plus rapide 😉
La meilleure solution, en terme de performance, pour trouver le minimum de ou maximum est de les naïfs algorithme que vous avez écrit (avec une seule boucle).
Mathématiques.max() est en fait as3 code compilé pour AVM2 opcodes, et en tant que tel n'est pas plus "natif" que n'importe quel autre code as3. En conséquence, il n'est pas nécessairement le plus rapide de mise en œuvre.
En fait, étant donné qu'il fonctionne sur type Tableau, il est plus lent que soigneusement code écrit avec Vecteur:
J'ai fait une rapide comparaison des performances de plusieurs naïf Vecteur et Matrice des implémentations de Mathématiques.max, en utilisant gskinner de PerformanceTest (Vecteur et Matrice remplie avec les mêmes Nombres aléatoires).
La manière la plus rapide Vecteur de la mise en œuvre semble être plus de 3x plus rapide que les Mathématiques.max avec les récentes AIR SDK/libération du joueur (flash player GAGNER 14,0,0,122 LIBÉRATION, compilé avec le SDK d'AIR 14):
en moyenne de 3,5 ms pour 1 000 000 de valeurs, par rapport aux Mathématiques.max() moyenne de 11 ms :
Conclusion est que si vous êtes préoccupé par la performance, vous devez utiliser de Vecteur au cours de la Matrice de partout où vous pouvez, en premier lieu, et ne pas toujours compter sur des implémentations par défaut, surtout quand ils forcer l'utilisation de la Matrice de
PS:même mise en œuvre pour chaque() de la boucle est 12x plus lent ...!
Cela dépend du monde réel les exigences de l'application.
Si votre question est purement hypothétique, puis les bases ont déjà été expliquées. C'est une recherche typique vs tri problème. Il a déjà été mentionné que algorithmiquement, vous n'allez pas obtenir mieux que O(n) dans ce cas.
Toutefois, si vous êtes à la recherche à un usage pratique, les choses deviennent plus intéressantes. Vous devez considérer la taille du tableau, et les processus impliqués dans l'ajout et la suppression de l'ensemble de données. Dans ces cas, il peut être préférable de prendre le calcul de " hit " à l'insertion /retrait par le tri à la volée. Les Insertions dans un pré-tri de tableau ne sont pas si cher que ça.
Le plus rapide de la réponse à la requête de la Min Max demande sera toujours à partir d'un tableau trié, parce que comme d'autres l'ont mentionné, il vous suffit de prendre le premier ou le dernier élément - vous un O(1) des coûts.
Pour un peu plus d'une explication technique sur le calcul des coûts impliqués, et de la notation Grand O, découvrez l'article de Wikipédia ici.
Nick.
Si vous êtes à la construction de la matrice de une fois et que vous voulez trouver le maximum d'une fois, le parcours est le meilleur que vous pouvez faire.
Lorsque vous souhaitez modifier le tableau et parfois envie de connaître la valeur maximale de l'élément, vous devez utiliser un File D'Attente De Priorité. L'une des meilleures structures de données qui est une Tas De Fibonacci, si c'est trop compliqué d'utiliser un Tas Binaire qui est plus lent, mais toujours bon.
Pour trouver le minimum et le maximum, juste à la construction de deux tas de changer le signe des nombres dans l'un d'eux.
Veuillez prendre en compte que le tri du tableau ne seront plus rapide que la boucle jusqu'à une certaine taille de la matrice. Si votre tableau est petit (et ça sera comme ça tout le temps), alors votre solution est parfaitement bien. Mais si elle pourrait obtenir trop grand, vous devez utiliser un conditionnel d'utiliser le tri approche lorsque le tableau est petit, et la normale itération quand il est trop grand
Si vous voulez trouver à la fois le min et max dans le même temps, la boucle peut être modifié comme suit:
Cela devrait se réaliser en O(n) moment.
Plus court chemin :
Mathématiques.min.appliquer(null,array); //ce sera le retour de valeur min de la matrice
Les mathématiques.max.appliquer(null,array); //ce sera le retour de max la valeur de la matrice
dans le cas contraire de se min & valeur maximale de la matrice de
Comme vous pouvez le voir, le code de ces deux fonctions est très similaire. La fonction définit une variable (max ou min) et puis traverse le tableau avec une boucle, la vérification de chaque élément suivant. Si l'élément suivant est plus élevé que le courant, réglez-le sur max (ou min). En fin de compte, retourner le nombre.
Il y a un certain nombre de façons cela peut être fait.
les comparaisons et 2N étapes)
Comment trouver le max. et min. dans le tableau à l'aide de minimum de comparaisons?
Si vous êtes vraiment paranoïaque à propos de la vitesse, la durée d'exécution & nombre de comparaisons, voir aussi
http://www.geeksforgeeks.org/maximum-and-minimum-in-an-array/
Algorithme MaxMin(premier, dernier, max, min)
//Cet algorithme magasins de la plus haute et la plus basse de l'élément
//Les valeurs globales de la matrice A dans les variables globales max et min
//tmax et tmin sont temporaires variables globales
Ci-dessous est la Solution à o(n):-
Étonné personne n'a mentionné le parallélisme ici.
Si vous avez vraiment un énorme tableau, vous pouvez utiliser en parallèle, sur sous-gammes.
À la fin de comparer tous les sous-gammes.
Mais le parallélisme vient de la largeur de quelques peine de trop, ne serait donc pas optimiser sur de petits tableaux. Toutefois, si vous avez obtenu d'énormes ensembles de données, il commence à faire sens, et vous obtenez un temps de division de la réduction de presque la quantité de fils de réaliser le test.
Trouver max les valeurs d'un tableau
Nous allons voir comment obtenir min, max valeurs à l'aide d'une seule fonction de
même chose peut faire pour trouver la valeur min
Après avoir lu tous les commentaires (merci de votre intérêt), j'ai trouvé que la "meilleure" façon (avec le moins de code, plus performant) pour ce faire, il a simplement trier le Tableau, puis prenez la première valeur du Tableau:
Cela fonctionne aussi pour un Tableau d'Objets - il vous suffit d'utiliser le Tableau.sortOn() et la fonction permet de spécifier une propriété:
J'espère que cela aide quelqu'un d'autre un jour!