indices des k plus grands éléments dans un des ménagères de longueur n de la matrice de
J'ai besoin de trouver les indices des k plus grands éléments d'un non triés, de longueur n, la matrice/vecteur en C++, avec k < n. J'ai vu comment utiliser nth_element() pour trouver le k-ième statistique, mais je ne suis pas sûr si ce est le bon choix pour mon problème comme il semble que j'aurais besoin de faire des appels k à nth_statistic, je pense qu'il aurait complexité O(kn), ce qui peut être aussi bon qu'il peut l'obtenir? Ou est-il un moyen de le faire juste en O(n)?
De la mettre en œuvre sans nth_element() semble que je vais avoir à parcourir l'ensemble du tableau une fois, le remplissage d'une liste d'indices de plus grands éléments à chaque étape.
Est-il quelque chose dans la bibliothèque C++ standard qui en fait un one-liner ou de toute manière intelligente de mettre en œuvre moi-même en quelques lignes? Dans mon cas particulier, k = 3 et n = 6, donc l'efficacité n'est pas une préoccupation majeure, mais il serait bien de trouver un endroit propre et efficace pour ce faire, pour arbitraire k et n.
Il ressemble Marque les N premiers éléments d'un tableau non trié est probablement le plus proche de poster je peux trouver, les affichages, il existe en Python et PHP.
Le vecteur peut être modifié, mais le résultat final doit être les indices du vecteur d'origine) des k plus grands éléments.
C'est juste un algorithme de sélection. Généralement, vous utiliserez soit tas de sélectionner ou de sélection rapide. Voir stackoverflow.com/q/7746648/56778 pour une question similaire. Il y a une réponse avec une bonne C++ solution. (à l'aide de priority_queue)
Par ailleurs, si k=3 et n=6, alors vous êtes probablement mieux de juste trier le tableau et choisir le top 3 des articles. Comme vous le dites, l'efficacité n'est pas une préoccupation majeure, et la différence entre O(kn) et O(n) est négligeable avec ces petits nombres.
OriginalL'auteur hazelnusse | 2013-02-15
Vous devez vous connecter pour publier un commentaire.
Voici mon application qui fait ce que je veux et je pense que raisonnablement efficace:
qui donne de sortie:
Il n'y a pas besoin d'ajouter tous les éléments de la file d'attente de priorité. Que fait l'algorithme O(n log n). Il peut être fait en O(n log k) si vous n'avez pas à ajouter des choses qui sont plus petit que le plus petit élément est déjà dans la file d'attente. Voir stackoverflow.com/q/7746648/56778 pour la discussion.
Je suis peut-être raté quelque chose, mais aussi loin que je peux voir, si j'ai seulement ajouter des éléments qui sont plus grand que le plus petit élément dans la file d'attente je peut finir par manquer de certains de la k-dessus des éléments. E. g si le premier élément que j'ai ajouter dans la file d'attente de priorité est l'élément maximum, il est en même temps le plus petit élément dans la file d'attente et aurait pour conséquence que l'algorithme ne pas ajouter des éléments.
Si vous regardez liée à répondre, vous verrez que vous avez initialement remplir la file d'attente de priorité avec la première
k
éléments. , vous pouvez utiliser le seul-ajouter-si-plus grand que le plus petit de la règle sur les éléments restants.Qu'en est-il quand il y a une cravate(s) avec k-ième plus grand élément? Serait agréable d'avoir cette extension à votre méthode.
OriginalL'auteur hazelnusse
La question a la réponse partielle; c'est-à
std::nth_element
renvoie la "le n-ième statistique" avec une propriété que aucun des éléments précédents nième sont plus que, et aucun des éléments suivants sont moins.Par conséquent, juste un appel à
std::nth_element
est suffisant pour obtenir les k plus grands éléments. Complexité temporelle O(n), qui est théoriquement la plus faible depuis que vous avez à visiter chaque élément au moins une fois pour trouver le plus petit (ou dans ce cas k le plus petit) élément(s). Si vous avez besoin de ces éléments k à être commandés, alors vous avez besoin de commander qui sera O(k log(k)). Alors, au total O(n + k log(k)).Eh bien, vous avez raison, et (en regardant de nouveau la question) je ne sais pas pourquoi j'ai donné cette réponse, en premier lieu, et pourquoi les gens en haut-voté. Mais plus que probablement, ils ont mal compris la question, tout comme moi, et apparemment, cette réponse a aidé d'une certaine façon, donc je vais le garder comme ça.
OriginalL'auteur Halil ŞEN
Cela devrait être une version améliorée de @hazelnusse qui est exécuté dans le
O(nlogk)
au lieu deO(nlogn)
OriginalL'auteur justHelloWorld
Vous pouvez utiliser la base de l'algorithme quicksort de faire ce que vous avez besoin, sauf qu'au lieu de la réorganisation des partitions, vous pouvez vous débarrasser des entrées de tomber de votre gamme désirée.
Il a été appelé "sélection rapide" et voici une implémentation C++ :
De SORTIE:
MODIFIER
Cette mise en œuvre a un O(n) temps d'exécution moyen; en raison de la méthode de sélection de pivot, il partage quicksort du pire cas de l'exécution. Par l'optimisation du choix de pivot, votre pire des cas aussi devient O(n).
OriginalL'auteur Mahmoud Al-Qudsi
De la bibliothèque standard de ne pas obtenir de vous une liste d'indices (il a été conçu pour éviter de passer des données redondantes). Toutefois, si vous êtes intéressé dans les n plus grands éléments, utilisez un certain type de partitionnement (les deux
std::partition
etstd::nth_element
O(n)):Vous pouvez définir un type de structure de vos éléments, de les stocker à la fois de la valeur et de l'indice d'origine, et en attendant de définir le comparateur.
OriginalL'auteur Richard Pump
Vous pouvez le faire dans
O(n)
temps avec un seul ordre statistique de calcul:r
être lek
-ième ordre statistiquebigger
etequal
.i
:array[i] > r
, ajouteri
àbigger
array[i] = r
, ajouteri
àequal
equal
jusqu'à ce que la somme des longueurs des deux listes estk
Naturellement, vous avez seulement besoin d'une liste si tous les éléments sont distincts. Et si nécessaire, vous pourriez faire des tours de combiner les deux listes en une seule, bien que ce serait rendre le code plus compliqué.
OriginalL'auteur Hurkyl
Même si le code suivant ne peuvent pas remplir le désiré de la complexité des contraintes, il pourrait être une alternative intéressante pour ladite file d'attente de priorité.
OriginalL'auteur Aleph0