Le moyen le plus rapide pour vérifier si un tableau est trié
Vu qu'il n'y est un tableau retourné par une fonction qui est de très grande taille.
Quel sera le fastest
approche pour tester si le tableau est trié?
Une approche la plus simple sera de:
///<summary>
///Determines if int array is sorted from 0 -> Max
///</summary>
public static bool IsSorted(int[] arr)
{
for (int i = 1; i < arr.Length; i++)
{
if (arr[i - 1] > arr[i])
{
return false;
}
}
return true;
}
y at-il seulement séquentiel des éléments?
Si vous voulez un meilleur algorithme que O(n), vous aurez à tolérer certaines erreurs.
Une autre solution pourrait être d'envelopper la liste dans un Flux de données (en supposant que vous savez le tableau est rempli, ce qui int[] dans votre exemple) et de les lire sizeof(int) octets à la fois, en les comparant avec la précédente octets lus. Que gagnerez-vous l'incrémentation de l'index du compteur, mais pas sûr de ce qu'il va faire pour la mise en cache.
Si vous voulez un meilleur algorithme que O(n), vous aurez à tolérer certaines erreurs.
Une autre solution pourrait être d'envelopper la liste dans un Flux de données (en supposant que vous savez le tableau est rempli, ce qui int[] dans votre exemple) et de les lire sizeof(int) octets à la fois, en les comparant avec la précédente octets lus. Que gagnerez-vous l'incrémentation de l'index du compteur, mais pas sûr de ce qu'il va faire pour la mise en cache.
OriginalL'auteur Cannon | 2012-08-16
Vous devez vous connecter pour publier un commentaire.
Vous aurez à visiter chaque élément du tableau pour voir si quelque chose n'est pas triée.
Votre O(n), dont l'approche est à peu près aussi rapide comme il est, sans aucune connaissance particulière sur le probable de l'état de la matrice.
Votre code spécifiquement tests si le tableau est trié avec des petites valeurs à la baisse des indices. Si ce n'est pas ce que vous souhaitez, votre si devient un peu plus complexe. Votre commentaire de code ne suggèrent qu'est ce que vous êtes après.
Si vous avez des connaissances particulières de la cause probable de l'état (dire, vous savez, il est généralement triés, mais de nouvelles données pourraient être ajoutés à la fin), vous pouvez optimiser l'ordre dans lequel vous visitez les éléments du tableau pour permettre le test à l'échec plus rapide lorsque le tableau est trié.
Vous pouvez tirer parti de la connaissance de l'architecture matérielle de vérifier plusieurs parties du tableau en parallèle par le partitionnement d'un tableau, d'abord en comparant les limites de la partition (fail fast check) puis l'exécution d'un tableau de partition par cœur sur un thread séparé (pas plus de 1 thread par CPU core). Notez cependant que si une matrice de partition est beaucoup plus petite que la taille d'une ligne de cache, les threads ont tendance à rivaliser les uns avec les autres pour l'accès à la mémoire contenant le tableau. Le Multithreading ne seront très efficaces pour assez grands tableaux.
OriginalL'auteur Eric J.
Plus rapide approche, la plate-forme cible: une unité centrale, Préférez 32 bits.
Un tableau trié avec 512 éléments: ~25% plus vite.
Cible: x64, même matrice: ~40% plus rapide.
Oublié un, peu moins rapide que mon premier bloc de code.
De la mesure (voir le vieillard du commentaire).
Cible: x64. Quatre cores/threads.
Un tableau trié avec 100 000 éléments: ~55%.
1 000 000 d'articles?
Oublions pourcentages.
Original: 0.77 ns/item, maintenant: 0.22 ns/item.
2 000 000 d'articles? Quatre noyaux: 4 fois plus rapide.
Est-ce à détecter les inversions? Bonne question! Wikipédia: Soit (Un(1),...,A(n)) une suite de n numéros distincts. Si i < j et A(i) > (j), alors la paire (i,j) est une inversion de A. - Si la séquence a des doublons, puis tous les chiffres ne sont distinctes. -Si une paire (i,j), isSorted utilise j = i + 1 , et(i) > (j), puis la séquence n'est pas triée, et, OUI, une inversion est détecté dans une séquence de pas nécessairement distincts numéros, nous avons terminé. Afin de ne PAS détecter les inversionS, mais si il détecte UNE inversion, alors nous savons que la séquence n'est PAS triée. J'ai ajouté un bloc de code "de la Mesure".
(Ne pas commenter les commentaires de demander de plus amples renseignements ou des précisions: modifier votre post. La partie qui a fait de moi un commentaire/je n'ai pas (encore) trouver idiomatiques:
ai <= (ai = a[i])
(et similaires).)Êtes-vous sûr que ces timings ont été prises avec un Communiqué de construire avec le débogueur n'est PAS attaché? Si le débogueur est attaché (c'est à dire que vous avez appuyé sur la touche F5 dans Visual Studio), puis votre timings ne pas refléter la façon dont le code sera exécuté dans la production. Sélectionnez "Exécuter sans Débogage" à partir du menu Débogage si vous voulez des timings.
Oui j'en suis sûr. Mes timings ont été prises avec une version Release (Optimiser le code "sur"). Je viens de vérifier sur un ralentissement de la machine, un ordinateur portable. Les résultats pour un tableau trié avec 512 éléments: une unité centrale, préférez 32 bits: 24%, x64: 35%. Et pour faire simple: exécuter sur votre système, vérifiez si mon approche est plus rapide (ou pas).
OriginalL'auteur P_P
Linq solution.
What will be the fastest approach to test if the array is sorted?
. Cette solution est au meilleur aussi vite que les OP de la solution, et sans doute un peu plus lent. Linq, peut être le nouveau noir, mais ce n'est pas la meilleure solution de tous les temps.En fait, cela pourrait échouer si le passé
Enumerable
est une itération-une fois la collecte. Par exemple, si quelqu'un à écrirex = IsSorted(File.ReadLines("filename.txt"));
la méthode échoue parce qu'il aurait besoin de plusieurs énumération desEnumerable
.OriginalL'auteur Raz Megrelidze
La seule amélioration que je peux penser à est de vérifier que les deux extrémités du tableau en même temps, ce peu de changement fera en deux temps...
ok, je comprends votre point, de toute façon si il ya quelque chose de mal qu'il pourrait trouver plus tôt, c'est lorsque l'erreur est dans le premier ou le quatrième trimestre de l'array
Puis à nouveau, vous permettra de le retrouver plus tard si la partie non triée est dans le milieu. Ajoute de la complexité, sans ajout de valeur. Plus vérification à partir des deux extrémités de réduire la probabilité que les données auxquelles vous accédez est dans le cache du PROCESSEUR (en fonction de la taille de la matrice et de l'architecture sous-jacente).
Sans compter que ce sera probablement plus lent en raison du comportement du cache.
pouvez-vous élaborer sur le cache de comportement?
OriginalL'auteur saul672
Cela pourrait ne pas être le plus rapide, mais c'est la solution complète. Chaque valeur avec de l'indice inférieure à ce que je est vérifié par rapport à la valeur actuelle à je. C'est écrit en php, mais peut être traduit facilement en c# ou javascript
tot
fur et à mesure. Y aurait-il une chance de capitaliser sur l'ordre des relations transitives?Je suis d'accord que le nombre de comparaisons fur et à mesure lors de la tot est grande cependant, nous ne pouvons pas assumer la séquence à transitive car nous ne savons pas ce que la séquence de commande est et si elle est transitive (par définition), il est supposé être déjà dans un certain type de commande.
Si vous ne pouvez pas supposer que la séquence de commande est transitive, alors il n'est pas possible de les trier en premier lieu. Tri dans le sens général implique la transitivité.
OriginalL'auteur atomCode
C'est ce que je suis venu avec et trouver des œuvres mieux, en particulier avec une plus grande taille des tableaux. La fonction est récursive et sera appelé pour la première fois, par exemple dans une boucle while comme ce
L'instruction if vérifie si les limites du tableau ont été atteint.
L'autre si l'instruction va s'appeler lui-même de manière récursive et pause à tout moment lorsque la condition devient fausse
This is what I […] find works better
a) mieux que ce à quoi? (Mieux que le code présenté dans la question?) b) mieux à ce sujet: comment puis-je reproduire le trouver?Désolé Michel, mais 1)Avez-vous testé votre solution, int[] arr = new int[]{0,0}, isSorted(arr,0) renvoie la valeur false (modifier "<" "<="). 2)Sur ma boîte, c'est (beaucoup) plus lent que l'OP de la solution. 3)Avec un grand tableau (int[] arr = new int[1000000]"): débordement de pile.
Salut @vieillard, oui je faisais référence au code présenté dans la question, à propos de la façon dont le temps d'exécution pour les grandes baies. Je l'ai essayé avec des échantillons de données aléatoires. Si vous trouvez que c'est autrement s'il vous plaît laissez-moi savoir
Je vous remercie, j'avais quelque peu oublié les cas où les éléments voisins sont égaux. J'avais testé la solution et a trouvé que c'était plus rapide pour les grands ensembles de données, cependant, je vais faire d'autres tests
OriginalL'auteur Michael Dera
La question qui me vient à l'esprit est "pourquoi"?
Est-ce pour éviter de re-trier une liste triée? Si oui, il suffit d'utiliser Timsort (norme en Python et Java). C'est assez bon à prendre avantage d'un tableau/liste déjà triée, ou presque triées. En dépit de la façon dont bon Timsort est à cela, il est mieux de ne pas trier à l'intérieur d'une boucle.
Une autre alternative est d'utiliser un discbased qui est foncièrement triés, comme un treap, rouge-noir arbre ou un arbre AVL. Ce sont de bonnes solutions de rechange pour le tri à l'intérieur d'une boucle.
Je dirais que la population initiale, vous n'avez pas trier un treap. Mise à jour d'un treap à l'intérieur d'une boucle n'est pas de tri - c'est la préservation de sortedness, ce qui est moins cher que le même Timsort.
OriginalL'auteur user1277476