Disons que j'ai un vecteur d'entiers:
std::vector<int> indices;
for (int i=0; i<15; i++) indices.push_back(i);
Ensuite, je le trie par ordre décroissant:
sort(indices.begin(), indices.end(), [](int first, int second) -> bool{return indices[first] > indices[second];})
for (int i=0; i<15; i++) printf("%i\n", indices[i]);
Cela produit les éléments suivants:
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
Maintenant, je veux que les chiffres 3, 4, 5 et 6 soient déplacés à la fin et garder l'ordre décroissant pour eux (de préférence sans avoir à utiliser sort
pour la deuxième fois). C'est à dire, voici ce que je veux:
14
13
12
11
10
9
8
7
2
1
0
6
5
4
3
Comment dois-je modifier la fonction de comparaison du std::sort
pour y parvenir?
return indices[first] > indices[second]
Tu ne veux pas direreturn first < second;
?std::greater
de<functional>
peut être utilisé à la place de votre lambda. En ce qui concerne votre question, l'écriture d'un comparateur plus détaillé qui garantit que vos valeurs comparent la façon dont vous le souhaitez pourrait être la façon la plus simple de le faire.return first > second
.Réponses:
Votre fonction de comparaison est incorrecte car les valeurs que vous obtenez en tant que
first
etsecond
sont les éléments dustd::vector
. Il n'est donc pas nécessaire de les utiliser comme indices. Donc, vous devez changerà
Maintenant, concernant le problème que vous essayez de résoudre ...
Vous pouvez laisser 3, 4, 5 et 6 hors de comparaison avec d'autres éléments et toujours les comparer les uns aux autres:
Démo
la source
Les fonctions de la bibliothèque d'algorithmes standards comme
iota
,sort
,find
,rotate
etcopy
rendrait la vie plus facile. Votre exemple se résume à:Production:
@TedLyngmo dans les commentaires montre bien qu'il pourrait / devrait être amélioré avec:
la source
auto b = a + 4;
est incorrect (si vous souhaitez conserver la cohérence avec l'extrait de code précédent). Cela devrait êtreauto b = a + 3;
dû au fait questd::rotate
vous l'utilisezb + 1
Solution 1
Approche simple avec un comparateur non linéaire .
Solution 2
Utilisation de
std::algorithm
s (partition)!Considérations sur les performances
Il peut sembler que la deuxième solution est plus lente en raison de la surcharge de la partition. Ce n'est probablement pas le cas, en raison de la prédiction du cache et des branches manquantes dans les processeurs modernes.
Référence
la source
n <= 6 && 3 <= n
en ce qui fonctionne le mieux pour le CPU cible afin que vous ne gagniez rien en introduisant les nombres 2 et 7 mais une confusion potentielle - et pourquoi prendre un pointeur sur le vecteur au lieu d'une référence?const
lecteur ne dit- il pas que la fonction ne change pas la valeur? Dans ce cas particulier d'un monoplace, cela peut être clair, mais ce n'est généralement pas le cas.