En utilisant C ++ et, espérons-le, la bibliothèque standard, je veux trier une séquence d'échantillons dans l'ordre croissant, mais je veux aussi me souvenir des index originaux des nouveaux échantillons.
Par exemple, j'ai un ensemble, ou un vecteur, ou une matrice d'échantillons A : [5, 2, 1, 4, 3]
. Je veux les trier B : [1,2,3,4,5]
, mais je veux aussi me souvenir des index originaux des valeurs, donc je peux obtenir un autre ensemble qui serait:
C : [2, 1, 4, 3, 0 ]
- qui correspond à l'index de chaque élément dans 'B', dans l'original ' UNE'.
Par exemple, dans Matlab, vous pouvez faire:
[a,b]=sort([5, 8, 7])
a = 5 7 8
b = 1 3 2
Quelqu'un peut-il voir une bonne façon de procéder?
for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
je préfère le standardstd::iota( idx.begin(), idx.end(), 0 );
#include <numeric>
pour iota ()iota
est l'algorithme le moins clairement nommé de toute la bibliothèque standard C ++.Vous pouvez trier std :: pair au lieu de simplement des entiers - le premier entier est les données d'origine, le second entier est l'index d'origine. Fournissez ensuite un comparateur qui ne trie que le premier entier. Exemple:
Triez la nouvelle instance de problème à l'aide d'un comparateur comme:
Le résultat de std :: sort sur v_prime, en utilisant ce comparateur, devrait être:
Vous pouvez décoller les indices en parcourant le vecteur, en saisissant .second de chaque std :: pair.
la source
Supposons que le vecteur donné soit
Créer un nouveau vecteur
Triez V et pendant le tri au lieu de comparer les éléments de V, comparez les éléments correspondants de A
la source
std::iota()
pour une initialisation plus élégante demap
J'ai écrit une version générique du tri d'index.
L'utilisation est la même que celle de std :: sort à l'exception d'un conteneur d'index pour recevoir les index triés. essai:
vous devriez obtenir 2 1 0 3. pour les compilateurs sans prise en charge de c ++ 0x, remplacez l'expression lamba comme modèle de classe:
et réécrire std :: sort as
la source
Maintenant
a
Contient à la fois nos valeurs et leurs indices respectifs dans le tri.a[i].first = value
ài
'th.a[i].second = idx
dans le tableau initial.la source
Je suis tombé sur cette question et j'ai compris que trier les itérateurs directement serait un moyen de trier les valeurs et de garder une trace des indices; Il n'est pas nécessaire de définir un conteneur supplémentaire de
pair
s de (valeur, index) qui est utile lorsque les valeurs sont de gros objets; Les itérateurs fournissent l'accès à la fois à la valeur et à l'index:comme pour l'exemple d'utilisation:
maintenant, par exemple, le 5e plus petit élément du vecteur trié aurait une valeur
**idx[ 5 ]
et son indice dans le vecteur d'origine seraitdistance( A.begin( ), *idx[ 5 ] )
ou tout simplement*idx[ 5 ] - A.begin( )
.la source
Il existe une autre façon de résoudre ce problème, en utilisant une carte:
Cela supprimera cependant les éléments non uniques. Si ce n'est pas acceptable, utilisez une carte multiple:
Pour afficher les indices, parcourez la carte ou la carte multiple:
la source
Belle solution par @Lukasz Wiklendt! Bien que dans mon cas, j'avais besoin de quelque chose de plus générique, je l'ai donc modifié un peu:
Exemple: Trouvez des indices triant un vecteur de chaînes par longueur, à l'exception du premier élément qui est un mannequin.
impressions:
la source
Pensez à utiliser
std::multimap
comme suggéré par @Ulrich Eckhardt. Juste que le code pourrait être encore plus simple.Donné
Trier dans le temps moyen d'insertion
Pour récupérer des valeurs et des indices d'origine
La raison de préférer a
std::multimap
à astd::map
est de permettre des valeurs égales dans les vecteurs d'origine. Veuillez également noter que, contrairement àstd::map
,operator[]
n'est pas défini pourstd::multimap
.la source
Faire un
std::pair
fonction in puis triez la paire:version générique:
idéone
la source
Les éléments du vecteur sont-ils uniques? Si oui, copiez le vecteur, triez l'une des copies avec STL Sort puis vous pourrez trouver l'index de chaque élément dans le vecteur d'origine.
Si le vecteur est censé gérer les éléments en double, je pense que vous feriez mieux d'implémenter votre propre routine de tri.
la source
Eh bien, ma solution utilise la technique des résidus. Nous pouvons placer les valeurs sous tri dans les 2 octets supérieurs et les indices des éléments - dans les 2 octets inférieurs:
Triez ensuite le tableau
myints
comme d'habitude:Après cela, vous pouvez accéder aux indices des éléments via residuum. Le code suivant imprime les indices des valeurs triées dans l'ordre croissant:
Bien sûr, cette technique ne fonctionne que pour les valeurs relativement petites du tableau d'origine
myints
(c'est-à-dire celles qui peuvent tenir dans les 2 octets supérieurs deint
). Mais il a l'avantage supplémentaire de distinguer des valeurs identiques demyints
: leurs indices seront imprimés dans le bon ordre.la source
Si c'est possible, vous pouvez créer le tableau de positions à l'aide de la fonction find, puis trier le tableau.
Ou peut-être pouvez-vous utiliser une carte où la clé serait l'élément, et les valeurs une liste de sa position dans les tableaux à venir (A, B et C)
Cela dépend des utilisations ultérieures de ces tableaux.
la source
Pour ce type de question Stockez les données du tableau d'origine dans de nouvelles données, puis recherchez en binaire le premier élément du tableau trié dans le tableau dupliqué et cet indice doit être stocké dans un vecteur ou un tableau.
Ici, la recherche binaire est une fonction qui prend le tableau, la taille du tableau, l'élément de recherche et retournerait la position de l'élément recherché
la source
Il y a plusieurs façons. Une solution assez simple consiste à utiliser un vecteur 2D.
Voici la sortie:
la source