Herramientas de usuario

Herramientas del sitio


cpp-avanzado:macros

¡Esta es una revisión vieja del documento!


Macros para programación competitiva

Notar que en todos los casos, cuando queremos hablar de un rango de números, indicamos sus extremos como $[A, B)$, es decir, utilizamos como extremos dos valores A y B de modo tal que los números del rango son aquellos $x$ que cumplen $A \leq x < B$. Esta elección de “fronteras”, que es cerrada a la izquierda, pero abierta a la derecha, es para casi toda tarea de programación la más conveniente, y se utiliza mucho en los lenguajes de programación como C++. También es la que más recomendamos, porque evita muchos errores y es más clara que otras, una vez que uno la conoce.

Iterar los números desde 0 hasta n-1 inclusive, con la variable i que es creada para el for:

#define forn(i,n) for(int i=0;i<int(n);i++)

Iterar los números desde s hasta n-1 inclusive, con la variable i que es creada para el for:

#define forsn(i,s,n) for(int i=int(s);i<int(n);i++)

Iterar los números desde n-1 hasta 0 inclusive, bajando con la variable i que es creada para el for:

#define dforn(i,n) for(int i=int(n)-1;i>=0;i--)

Iterar los números desde n-1 hasta s inclusive, bajando con la variable i que es creada para el for:

#define dforsn(i,s,n) for(int i=int(n)-1;i>=int(s);i--)

Las siguientes macros son cómodas para iterar una colección hacia adelante o hacia atrás, si nos interesa tener acceso al iterador y no solamente a los elementos iterados. Eran necesarias (utilizando typeof en lugar de auto) antes de c++11 para iterar sets y maps, pues no existía el foreach.

#define forall(i,c) for(auto i = (c).begin(); i != (c).end(); i++)
#define dforall(i,c) for(auto i = (c).rbegin(); i != (c).rend(); i++)

La siguiente es muy útil para utilizar con funciones de STL, donde se suele pedir un rango mediante dos iteradores, para pasar directamente una colección completa.

#define all(c) (c).begin(),(c).end()

El uso más común de todos es al llamar a la función sort, con sort(all(v)) por ejemplo, siendo v un vector. Sin embargo es útil con muchísimas funciones de la STL, como podría ser por ejemplo una instrucción find(all(v), 27).

La siguiente sirve para consultar si un elemento está en un set (o map: en un map, se consulta si el elemento dado es una clave del diccionario).

#define esta(x,c) ((c).find(x) != (c).end())

Las siguientes son muy útiles para buscar y corregir errores en programas:

#define DBG(x) cerr << #x << " = " << (x) << endl
#define RAYA cerr << "===============================" << endl

DBG es una macro particularmente bonita y “mágica”. Si escribimos en una línea DBG(x); en el código, siendo x una variable (o podría ser una expresión), nos mostrará su valor y su nombre por pantalla. Alentamos a probarla para ver su utilidad a la hora de buscar bugs en programas.

Similarmente, RAYA; muestra una clara línea separadora: esto es especialmente útil cuando tenemos un for y queremos mostrar los valores en cada iteración. Poniendo un RAYA;, podemos separar con facilidad los valores entre iteraciones.

Los siguientes typedef son razonables y cómodos en programación competitiva:

typedef long long tint;
typedef long double tdbl;
typedef vector<int> vint;
typedef pair<int,int> pint;
typedef pair<tint,tint> ptint;
cpp-avanzado/macros.1506097678.txt.gz · Última modificación: 2017/09/22 16:27 por santo