Digamos que tengo un vector de enteros:
std::vector<int> indices;
for (int i=0; i<15; i++) indices.push_back(i);
Luego lo ordeno en orden descendente:
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]);
Esto produce lo siguiente:
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
Ahora quiero que los números 3, 4, 5 y 6 se muevan hasta el final, y mantener el orden descendente para ellos (preferiblemente sin tener que usarlos sort
por segunda vez). Es decir, esto es lo que quiero:
14
13
12
11
10
9
8
7
2
1
0
6
5
4
3
¿Cómo debo modificar la función de comparación de std::sort
para lograr eso?
return indices[first] > indices[second]
No quiere decirreturn first < second;
?std::greater
desde<functional>
se puede usar en lugar de su lambda. En cuanto a su pregunta, escribir un comparador más detallado que garantice que sus valores se comparen de la manera deseada puede ser la forma más fácil de hacerlo.return first > second
.Respuestas:
Su función de comparación es incorrecta ya que los valores que obtiene como
first
ysecond
son los elementos destd::vector
. Por lo tanto, no hay necesidad de usarlos como índices. Entonces, necesitas cambiara
Ahora, con respecto al problema que intentas resolver ...
Puede dejar 3, 4, 5 y 6 fuera de comparación con otros elementos y aún compararlo entre sí:
Manifestación
fuente
Funciones de la biblioteca de algoritmos estándar como
iota
,sort
,find
,rotate
ycopy
harían la vida más fácil. Su ejemplo se reduce a:Salida:
@TedLyngmo en los comentarios señala que podría / debería mejorarse con:
fuente
auto b = a + 4;
está mal (si desea mantener la coherencia con el fragmento anterior). Debería serauto b = a + 3;
porque en elstd::rotate
usob + 1
Solución 1
Enfoque directo con un comparador no lineal .
Solución 2
Usando
std::algorithm
s (partición)!Consideraciones de rendimiento
Puede parecer que la segunda solución es más lenta debido a la sobrecarga de la partición. Probablemente no lo sea, debido a la predicción de caché y rama errónea en los procesadores modernos.
Punto de referencia
fuente
n <= 6 && 3 <= n
en lo que funcione mejor para la CPU de destino, de modo que no gane nada introduciendo los números 2 y 7 sino una posible confusión, y ¿por qué tomar un puntero al vector en lugar de una referencia?const
dice al lector que la función no cambia el valor? En este caso particular de una línea, puede ser claro, pero en general no lo es.