Debería usar
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
o
std::sort(numbers.rbegin(), numbers.rend()); // note: reverse iterators
ordenar un vector en orden descendente? ¿Hay algún beneficio o inconveniente con un enfoque u otro?
reverse_iterator
la de.std::sort(b, e);
pone el mínimo enb
(en nuestro casorbegin
, por lo que el último elemento) y el máximo ene
(en nuestro casorend
, por lo que el primer elemento).Respuestas:
En realidad, el primero es una mala idea. Use el segundo o este:
De esa manera, su código no se romperá silenciosamente cuando alguien decida que
numbers
debería retenerlong
o enlong long
lugar deint
.fuente
greater
el otro?rbegin
yrend
fueron hechos para un propósito específico.std::greater<typename decltype(numbers)::value_type>()
o algo así?std::greater<>()
desde C ++ 14.Usa el primero:
Es explícito de lo que está pasando - menos posibilidades de mala interpretación
rbegin
quebegin
, incluso con un comentario. Es claro y legible, que es exactamente lo que quieres.Además, el segundo puede ser menos eficiente que el primero dada la naturaleza de los iteradores inversos, aunque tendría que perfilarlo para estar seguro.
fuente
Con c ++ 14 puedes hacer esto:
fuente
¿Qué hay de esto?
fuente
=
y+
son solo conveniencias∈
y significado∪
. En ese caso,O(n*log(n)) + O(n)
es una notación conveniente para laO(n*log(n)) ∪ O(n)
cual es lo mismo queO(n*log(n))
. La palabra "cálculo" es una buena sugerencia y tiene razón sobre el tono.En lugar de un functor como propuso Mehrdad, podría usar una función Lambda.
fuente
Según mi máquina, ordenar un
long long
vector de [1..3000000] usando el primer método toma alrededor de 4 segundos, mientras que usar el segundo toma aproximadamente el doble del tiempo. Eso dice algo, obviamente, pero tampoco entiendo por qué. Solo piensa que esto sería útil.Lo mismo reportado aquí .
Como dijo Xeo,
-O3
usan casi el mismo tiempo para terminar.fuente
reverse_iterator
operaciones no estuvieran alineadas, y dado que son solo un contenedor alrededor de los iteradores reales, no es de extrañar que tomen el doble de tiempo sin alinearse.base()
función miembro, por ejemplo, devuelve el iterador envuelto.std::vector<>::reverse_iterator
se implemente en términos destd::reverse_iterator<>
. Extraño; hoy aprendí. :-PPuede usar el primer enfoque debido a que obtiene más eficiencia que el segundo.
La complejidad temporal del primer enfoque es menor que la segunda.
fuente
fuente
TL; DR
Usar cualquier. Son casi lo mismo.
Respuesta aburrida
Como de costumbre, hay pros y contras.
Uso
std::reverse_iterator
:operator>()
std::greater<int>()
Usar
std::greater
cuando:En cuanto al rendimiento, ambos métodos son igualmente eficientes. Probé el siguiente punto de referencia:
Con esta línea de comando:
std::greater
demostd::reverse_iterator
demoLos tiempos son iguales. Valgrind informa el mismo número de errores de caché.
fuente
No creo que deba usar ninguno de los métodos en la pregunta, ya que ambos son confusos, y el segundo es frágil, como sugiere Mehrdad.
Yo recomendaría lo siguiente, ya que parece una función de biblioteca estándar y deja en claro su intención:
fuente
std::greater
comparador ...Puede usar el primero o probar el siguiente código, que es igualmente eficiente
fuente