Comment puis-je trouver ce qui précède sans supprimer le plus grand élément et à la recherche de nouveau? Y a-t-il un moyen plus efficace de faire cela? Peu importe si ces éléments sont des duplicats. P>
11 Réponses :
Créer un subliste de n..m, triez-le décroissant. Puis attrapez les deux premiers éléments. Supprimer ces éléments de la liste orginale. P>
en utilisant Partial_sort ? Un exemple: p>
+1 Je ne savais pas à propos de Partial_sort. Mais ne fonctionne pas s'il veut garder l'ordre de la liste d'origine.
Vous pouvez utiliser partal_sort_copy pour cela
Est-ce que cela ne vous obtiendra pas les plus petits éléments? Il est assez facile de réparer en utilisant un opérateur de comparaison différent. +1
Oui, j'écris la même chose. Merci
Et si vous diffusez un grand nombre de valeurs à travers, disons à partir d'un INPUT_ITERATOR et ne voulez pas stocker toute la plage, seuls les éléments supérieurs, puis les opérations de tas - make_heap, push_heap et sort_heap - sont le moyen de aller.
Quelle est la différence de juste std :: tri (atest.begin (), atest.end ()); code>? ATEST [0] - Le plus grand, ATEST [1] - deuxième plus grand.
partielle_sort a la capacité particulière d'arrêter de trier lorsque seuls les premiers n éléments doivent être triés. (Deuxième argument)
Une idée de la complexité de temps?
De Josuttis --- Partial_sort () Garanties N * Log (n) Complexité dans tous les cas. Normalement entre les comparaisons linéaires et N-log-n (environ numéros-éléments *
suppose que vous voulez dire que vous voulez trouver les deux plus grandes valeurs uniques de la liste.
Si la liste est déjà triée, alors regardez simplement le deuxième dernier élément (ou plutôt, itérer à partir de la fin à la recherche de la deuxième dernière valeur. ). P>
Si la liste est non achouée, alors ne vous inquiétez pas pour le trier. Le tri est au meilleur O (n lg n). Une itération linéaire simple est O (n), donc simplement une boucle sur les éléments suivant la piste: p> Il y a bien sûr d'autres critères, et ceux-ci pourraient tous être mis dans le test à l'intérieur. la boucle. Toutefois, si vous voulez dire que deux éléments qui ont la même valeur la plus importante devraient être trouvés, vous devez envisager de savoir ce qui se passe aurait trois éléments ou plus ont tous la valeur la plus importante, ou si deux ou plusieurs éléments ont la deuxième plus grande. P > p>
Sauf que cela ne gère pas les doublons dans la liste
Besoin d'un bloc d'autre si second_best <* i
Je n'ai pas besoin de trouver des valeurs uniques, les doublons sont corrects - j'ai mis à jour cela dans la question.
for (e: all elements) { if (e > largest) { second = largest; largest = e; } else if (e > second) { second = e; } } You could either initialize largest and second to an appropriate lower bound, or to the first two items in the list (check which one is bigger, and don't forget to check if the list has at least two items)
Simple à coder ... Que pouvez-vous demander plus? Certes, faire une recherche est moins "complexe" mais sera certainement certainement plus lente en raison de l'accès à la mémoire amusant.
Le tri est par définition plus lentement, car vous devez inspecter des éléments au moins O (n log n). Ceci est garanti pour inspecter uniquement les éléments o (n) fois (où n est #Exements bien sûr). Ce n'est que si l'opération doit être répétée sur le même tri de la liste devient plus efficace.
C'est ce que j'ai fini par la mise en œuvre (aurait dû mentionner probablement qu'en OP), mais je cherchais quelque chose de différent (et éventuellement plus rapide).
Le tri peut être fait dans moins de lignes et la récupération des éléments les plus gros / les plus petits est très efficace sur une liste déjà triée, mais vous devrez payer un coût plus important à l'avant pour le faire trier. C'est cependant la solution la plus efficace possible si vous recherchez uniquement un ensemble (dans ce cas 2) Nombre d'articles les plus importants.
Vous pouvez numériser la liste en une seule passe et enregistrer les valeurs 1 er et 2nd, qui comporte une efficacité O (n) pendant le tri (n journal n). P>
EDIT:
Je pense que ce genre partiel est O (n log K) p>
La réponse dépend si vous ne voulez que les valeurs, ou aussi des itérateurs pointant sur les valeurs.
Modification mineure de @Will Réponse. P>
v::value_type second_best = 0, best = 0; for(v::const_iterator i=v.begin(); i!=v.end(); ++i) { if(*i > best) { second_best = best; best = *i; } else if (*i > second_best) { second_best = *i; } }
NTH_Element (commencer, commencer + n, fin, comparer) code> place l'élément qui serait NTH (où "premier" est "0ème") si la plage
[commence, fini) code> ont été triés à la position
commencements + n code> et veille à ce que tout de
[commence, commence + n) code> apparaisse avant le nième élément de la liste triée. Donc, le code que vous voulez est:
nth_element(container.begin(),
container.begin()+1,
container.end(),
appropriateCompare);
L'algorithme optimal ne devrait pas avoir besoin de plus de 1,5 * N - 2 comparaisons. (Une fois que nous avons décidé que c'est O (n), quel est le coefficient devant N? 2 * N comparaisons est inférieur à optimal). P>
Alors, déterminez d'abord le «gagnant» et le «perdant» dans chaque paire - c'est 0,5 * N comparaisons. P>
Déterminez ensuite le plus grand élément en comparant les gagnants - c'est une autre comparaison de 0,5 * N-1. P>
Déterminez ensuite le deuxième plus gros élément en comparant le perdant de la paire où le plus grand élément provenait contre les gagnants de toutes les autres paires - une autre comparaisons de 0,5 * N-1. P>
Comparaisons totales = 1.5 N - 2. P>
non testé mais amusant:
Si le plus grand est le premier élément, recherchez le deuxième plus grand de [plus grand + 1, fin). Sinon, recherchez dans [Commencer, plus grand) et [plus grand + 1, fin) et prenez le maximum des deux. Bien sûr, cela a O (2n), donc ce n'est pas optimal.
Si vous avez des itérateurs d'accès aléatoire, vous pouvez le faire comme un tri rapide et utiliser la récursion toujours élégante: p> ceci a o (n) et devrait T faire plus de comparaisons que Mise en œuvre de Nomen A >. p> p>
top k est généralement un peu meilleur que n (journal k) bien sûr le Pas aussi bon qu'un algo spécialisé pour exactement 2 mais pour fixe moyenne pire est que je devinerais n (k-1) + 2) quand dans l'ordre opposé et tout distinct. p> meilleur est 2n + k (journal k) pour le k meilleur étant le premier p> p> spécial_allocator code> peut-il être juste un tableau de k multiiset value_types et une liste de ces nœuds (qui n'a généralement rien à ce poste car les autres K sont utilisées dans le multiviseur jusqu'à ce que son temps puisse en mettre un nouveau et que nous effilons, puis immédiat de la réutiliser. Bien d'avoir cela ou d'autre que l'alloc de mémoire / gratuit dans STD :: Multiset et la ligne de cache La merde tue Ya. C'est un peu de travail (très) minuscule pour lui donner un état statique sans violer les règles d'allocator stl. P>
k << n code>, je devinerais (2n + delta * n) où Delta est petit - My Dek ACP Vol3 S & S est emballé et une estimation sur Delta est un peu plus de travail. que je veux faire. p>