0Pricing
C++ Academy · Lección

Comparadores personalizados

Controle el orden

Comparadores personalizados es una lección gratuita de C++ Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C++ Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C++ Academy incluye 4 lecciones en total.

¿Por qué usar comparadores personalizados?

De forma predeterminada, los contenedores ordenados utilizan std::less (orden ascendente). Un comparador personalizado permite cambiar ese orden, por ejemplo, a descendente o según un campo específico.

#include <iostream>
#include <set>

int main() {
    std::set<int> ascending{3, 1, 2};
    for (int x : ascending) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Orden descendente con std::greater

El comparador personalizado más sencillo es el functor estándar std::greater, que ordena de forma descendente.

#include <iostream>
#include <set>
#include <functional>

int main() {
    std::set<int, std::greater<int>> s{3, 1, 2};
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Comparador en un map

El comparador es el tercer parámetro de plantilla de std::map. Aquí las claves se ordenan de mayor a menor.

#include <iostream>
#include <map>
#include <functional>

int main() {
    std::map<int, std::string, std::greater<int>> m{
        {1, "one"}, {3, "three"}, {2, "two"}
    };
    for (const auto& [k, v] : m) std::cout << k << ':' << v << ' ';
    std::cout << '\n';
    return 0;
}

Cómo funcionan los comparadores

Un comparador es un objeto invocable que recibe dos argumentos y devuelve true si el primero debe ir antes que el segundo. Debe definir un orden débil estricto.

#include <iostream>

struct Less {
    bool operator()(int a, int b) const { return a < b; }
};

int main() {
    Less cmp;
    std::cout << std::boolalpha << cmp(2, 5) << '\n';
    std::cout << cmp(5, 2) << '\n';
    return 0;
}

Un comparador de struct personalizado

Defina su propio struct functor con operator() y pase su tipo como comparador.

#include <iostream>
#include <set>

struct ByAbs {
    bool operator()(int a, int b) const {
        return (a < 0 ? -a : a) < (b < 0 ? -b : b);
    }
};

int main() {
    std::set<int, ByAbs> s{-5, 3, -1, 4};
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Ordenar cadenas por longitud

Los comparadores pueden comparar cualquier propiedad. Aquí las cadenas se ordenan por longitud y, en caso de empate, alfabéticamente.

#include <iostream>
#include <set>
#include <string>

struct ByLen {
    bool operator()(const std::string& a, const std::string& b) const {
        if (a.size() != b.size()) return a.size() < b.size();
        return a < b;
    }
};

int main() {
    std::set<std::string, ByLen> s{"bbb", "a", "cc", "dd"};
    for (const auto& x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Por qué son importantes los desempates

Si su comparador indica que ninguno de los elementos va antes que el otro, el contenedor los considera iguales. En un set, eso significa que uno se descarta como duplicado.

#include <iostream>
#include <set>
#include <string>

struct LenOnly {
    bool operator()(const std::string& a, const std::string& b) const {
        return a.size() < b.size();
    }
};

int main() {
    std::set<std::string, LenOnly> s{"ab", "cd", "x"};
    std::cout << s.size() << " elements\n";
    return 0;
}

Lambdas como comparadores

Puede usar una lambda pasando su tipo mediante decltype y la propia lambda al constructor.

#include <iostream>
#include <set>

int main() {
    auto cmp = [](int a, int b) { return a > b; };
    std::set<int, decltype(cmp)> s(cmp);
    s.insert(1);
    s.insert(3);
    s.insert(2);
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Comparadores en priority_queue

Los comparadores también configuran std::priority_queue. Con std::greater, se convierte en un min-heap.

#include <iostream>
#include <queue>
#include <vector>
#include <functional>

int main() {
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq;
    pq.push(5); pq.push(1); pq.push(3);
    while (!pq.empty()) { std::cout << pq.top() << ' '; pq.pop(); }
    std::cout << '\n';
    return 0;
}

Comparar pares

Para ordenar un conjunto de pares por el segundo elemento, escriba un comparador que examine .second.

#include <iostream>
#include <set>
#include <utility>

struct BySecond {
    bool operator()(const std::pair<int,int>& a, const std::pair<int,int>& b) const {
        return a.second < b.second;
    }
};

int main() {
    std::set<std::pair<int,int>, BySecond> s{{1, 9}, {2, 3}, {3, 6}};
    for (const auto& p : s) std::cout << p.first << ':' << p.second << ' ';
    std::cout << '\n';
    return 0;
}

Comparadores transparentes

Usar std::less<> (con corchetes angulares vacíos) habilita la búsqueda heterogénea en C++14 y evita conversiones temporales de claves.

#include <iostream>
#include <set>
#include <functional>

int main() {
    std::set<int, std::less<>> s{1, 2, 3};
    std::cout << (s.find(2) != s.end() ? "found" : "no") << '\n';
    return 0;
}

Comprobación rápida

Compruebe su comprensión de cómo los comparadores definen la igualdad.

Resumen

Ha aprendido que los comparadores personalizados:

  • cambian el orden mediante el parámetro de plantilla del comparador del contenedor
  • pueden ser std::greater, un struct functor o una lambda (mediante decltype)
  • definen la igualdad mediante equivalencia, por lo que siempre debe incluir un desempate para evitar perder elementos distintos

Siguiente curso: búsquedas rápidas basadas en hash con std::unordered_map.

Preguntas frecuentes

¿La lección «Comparadores personalizados» es gratis?

Sí — el texto completo de «Comparadores personalizados» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C++ Academy, actualiza a CoddyKit PRO. El curso de C++ Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Comparadores personalizados»?

Controle el orden Practicas C++ Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C++ Academy?

No se requiere experiencia previa. C++ Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Comparadores personalizados»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C++ Academy?

Sí. Cada lección de C++ Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. std::map
  2. std::set
  3. multimap y multiset
  4. Comparadores personalizados
← Volver a C++ Academy