Evidentemente, saber qué hace cada parte de C++. No son muchas las herramientas que se usan, así que no sean culias y apréndanse eso. Entender las estructuras de while, for, if, else if.
Importante tener en cuenta el ámbito (o scope) de una variable.
Para los for está bueno primero hacer es el "cálculo del rango". Es decir, si yo tengo, por ejemplo:
const int N = 4;
for (int i = 0; i < N-2; i++) {
cuerpo del for
}
Lo primero que deberíamos hacer es ver para cuáles valores de i se ejecutará el cuerpo de la función.
En este caso, i ∈ {0, 1}, es decir, este es el conjunto tal que satisface la condición.
Luego, se deberá hacer los casos para cada i.
i = 0:
cuerpo con i = 0
actualización de variables
i = 1:
cuerpo con i = 1
actualización de variables
En una parte de la hoja sería ideal tener anotadas todas las variables e ir actualizándolas a medida que cambian.
Un buen tip es siempre intentar entender qué está haciendo cierta función o parte de código. Esto ahorrará tiempo y evitará problemas de cálculos. Quizás nos damos cuenta de que toda una función fea de interpretar simplemente te dice si un número es primo o no, entonces es cuestión de que nosotros hagamos esa parte en vez de seguir línea a línea el código.
Algo esencial es ver qué se está pidiendo de salida. Si es el cout de una variable particular o qué. Esto puede también ser un facilitador porque quizás tenemos una variable que cambia mucho dentro del programa que al final no importaba seguir porque no influía en nada.
Siempre que aparezcan distintas funciones en el código, ir directamente a la función main y guiarse de ahí. Recordar que el main orquesta toda la ejecución del programa.
#include <iostream>
using namespace std;
const int N = 10;
int main()
{
int datos[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < N; i++)
cout << datos[(i+4)%N)];
}
Primero lo primero: ver para cuáles i es válida la condición del for.
A mí me gusta anotarlo así:
i ∈ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Y ahora vemos qué hacemos para cada i. Dice que muestra por pantalla datos[(i+4)%N].
A ver, hagamos la lectura para los distintos i. Para esto yo haría algo así.
Para i = 0:
datos[(0+4)%N)]
// como N = 10 y 0 no cambia nada, queda igual a
datos[4%10]
// 4 % 10 es simplemente 4, por lo que queda
datos[4]
// y esto devuelve
5
Para i = 1:
datos[(1+4)%10]
// resuelvo
datos[5]
// y esto devuelve
6
Vamos intentando entender qué hace el siguiente código. Dado un índice i, obtenemos el elemento i + 4, pero como es módulo 10, entonces cuando llegamos a 10 se reinicia. O sea, para cada i la expresión irá siendo:
datos[4]
datos[5]
datos[6]
datos[7]
datos[8]
datos[9]
datos[0]
datos[1]
datos[2]
datos[3]
Y haciendo un cout de cada uno quedaría: 5678901234, que sería el resultado final del ejercicio.
#include <iostream>
using namespace std;
const int N = 5;
int main()
{
int datos[N] = {1, 2, 3, 4, 5};
int limite_superior = N - 3;
int limite_inferior = 0;
for (int i = limite_inferior; i<limite_superior; i++)
datos[i] = datos[limite_superior-i];
for (int i = 0; i<N; i++)
cout << datos[i];
}
Vamos primero anotando las variables y sus valores. Imaginemos que tengo una hoja y anoto lo siguiente en la esquina superior izquierda:
limite_superior = 2 // que viene de hacer 5 - 3
limite_inferior = 0
datos[N] = {1, 2, 3, 4, 5}
Y cada vez que hagamos un cambio (porque ya veo que dentro del for se está sobrescribiendo a datos) vamos actualizando las variables.
Ahora vemos los i que satisfacen la condición del primer for.
A mí me gusta anotarlos como
i ∈ {0, 1}
Porque empieza en 0 (limite_inferior) y suma de a uno hasta que se llegue a 2 (limite_superior) sin incluirlo.
Ejecutando el primer for para cada i para la expresión datos[i] = datos[limite_superior-i]:
Para i = 0,
datos[0] = datos[2]
Esto sería, guardar lo que está en datos[2] en datos[0]. datos[2] vale 3, así que datos[0] = 3.
ACTUALIZAMOS DATOS
datos[N] = {3, 2, 3, 4, 5}
Continuando con el siguiente i:
Para i = 1
datos[1] = datos[2-1]
que es lo mismo que
datos[1] = datos[1]
Esto no cambiará nada. "Guardar en datos[1] lo que está en datos[1]". O sea, no cambia nada.
Vamos con el siguiente for.
for (int i = 0; i<N; i++)
cout << datos[i];
Lo único que hace es recorrer el vector datos para mostrarlo con un por pantalla.
Entonces, el resultado sería: 32345.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
const int DIM = 5;
int num[DIM] = {3, 4, 4, 4, 5};
int i, valM, valm, posM, posm;
posM = 0;
posm = 0;
valm = num[posm];
valM = num[posM];
for (i = 1; i < DIM - 2; i++)
{
if (num[i] > valM)
{
valM = num[i];
posM = i;
}
if (num[i] < valm)
{
valm = num[i];
posm = i;
}
}
cout << posM << "-" << posm << ":" << abs(valM - valm);
}
Anotamos las variables y sus valores, haciendo las evaluaciones correspondientes (es decir, no ponemos num[posm] sino que ya escribimos cuánto vale posM y qué devuelve el vector num en esa posición).
Variables:
posM = 0
posm = 0
valm = 3 // de evaluar num en 0
valM = 3 // de evaluar num en 0
Lo de siempre, ver qué valores de i que satisfacen la condición del for.
Los i válidos son:
i ∈ {1, 2}
Porque empieza en 1, suma uno por cada iteración (i++) y va hasta (sin incluir) DIM - 2, es decir, 3.
Ahora, para cada i tenemos que hacer estos if.
if (num[i] > valM)
{
valM = num[i];
posM = i;
}
if (num[i] < valm)
{
valm = num[i];
posm = i;
}
Pensemos qué hacen esos condicionales.
El primero guarda en valM cualquier valor que sea mayor al valM anterior, y en posM guarda su posición. Esto es, en valM se guardará el valor más grande y en valM la posición donde se encuentra el valor más grande.
El segundo guarda en valm el mínimo, y en posm la posición donde se encuentra el valor mínimo.
Peeeero peero pero, NOTAR QUE el for recorrerá hasta i = 2. Entonces en posM y posm guardán el mínimo y máximo que encuentre en los primeros tres elementos del vector.
Veamos el vector nuevamente: {3, 4, 4, 4, 5}
Y como únicamente vemos los primeros 3 elementos (porque el elemento 0 y la posición 0 se guardan antes del for, y el for va de 1 a 2) tomemos nomás {3, 4, 4}. El mínimo es el 3 y está en la posición 0, entonces
valm = 3
posm = 0
Tal como estaba antes.
El máximo es el 4 y está en la posición 1 (porque para que se actualice debería ser estrictamente mayor, no mayor igual), entonces
valM = 4
posM = 1
Y el resultado el ejercicio viene de la última expresión
cout << posM << "-" << posm << ":" << abs(valM - valm);
Que será: 1-0.1.
Recordar que abs es el valor absoluto, que es simplemente "sacar" el signo que tiene un número. Si es 7, abs(7) es 7, y si es -7, abs(-7) es 7.
#include <iostream>
using namespace std;
int main()
{
const int DIM = 5;
int num[DIM] = {3, 3, 4, 7, 5};
int val, i, pos;
pos = 0;
val = num[pos];
for (i = 1; i < DIM; i++)
if (num[i] < val)
{
val = num[i];
pos = i;
}
cout << pos << ":" << val;
}
Escribamos las variables de interés y sus valores
pos = 0
val = 3
Bien, ahora veamos que ese for recorre todo el vector, porque va de i = 1 hasta DIM. Para i = 0 ya lo guarda en pos y num[0] en val antes del for.
Veamos que el if está preguntando por un elemento de num que sea menor al guardado en val. Si esto sucede, actualiza val con ese valor. También guarda en qué i sucede esto. Entonces podemos decir que este for está buscando al menor número del vector y guarda también la posición.
El resultado viene dado por la expresión final:
cout << pos << ":" << val;
Veamos al vector {3, 3, 4, 7, 5} y vemos que el menor número es el 3, que se encuentra en la posición 0. Hay otro 3 en el segundo lugar, pero para que se actualice val es necesario que sea menor estricto.
Entonces, el resultado final es: 0:3.
#include <iostream>
using namespace std;
const int N = 5;
void incrementar_elemento(int arreglo[], int valor)
{
for (int i = 0; i < N; i++)
if (arreglo[i] == valor)
arreglo[i]++;
}
void incrementar(int &valor)
{
valor++;
}
int main()
{
int datos[N] = {1, 2, 3, 4, 5};
int referencia = 5;
incrementar_elemento(datos, referencia);
incrementar(referencia);
incrementar_elemento(datos, referencia);
for (int i = 0; i < N; i++)
cout << datos[i];
}
Según mi tip número 7, cuando se tienen funciones se debe ver primero la función main y de ahí arrancar. También será de mucha utilidad el tip número 5, que dice de entender qué hace un pedazo de código. Ahora intentaremos entender qué hace cada función, especialmente guiándonos de los nombres.
Comenzamos, vamos al main.
Anotemos las variables.
datos[N] = {1, 2, 3, 4, 5}
referencia = 5
Luego, se llama a la función incrementar_elemento(datos, referencia). Veamos el código de tal función y busquemos entender qué hace, porque luego se la llama de vuelta y podremos ahorrar tiempo.
void incrementar_elemento(int arreglo[], int valor)
{
for (int i = 0; i < N; i++)
if (arreglo[i] == valor)
arreglo[i]++;
}
Para cada i entre 0 y N, siendo N una constante entera que define los largos de los vectores, hay un if que pregunta por un elemento que sea igual al valor pasado como argumento. Si eso ocurre, incrementa en uno ese valor.
Está bueno poner en palabras lo que hace una función sin hacer literalmente la función paso a paso para saber qué devuelve.
Entonces, cuando hacemos incrementar_elemento(datos, referencia), siendo datos igual a {1, 2, 3, 4, 5} y referencia igual a 5, entonces donde haya 5 se incrementará en uno.
ACTUALIZACIÓN DE VARIABLES
datos[N] = {1, 2, 3, 4, 6}
referencia = 5
Luego el main dice de hacer incrementar(referencia), que es lo mismo que hacer referencia++ (uno podía intuirlo ya sin leer el código de la función incrementar).
ACTUALIZACIÓN DE VARIABLES
datos[N] = {1, 2, 3, 4, 6}
referencia = 6
Se sigue con llamar nuevamente a incrementar_elemento con datos y referencia.
Si teníamos {1, 2, 3, 5, 6} y ahora buscamos incrementar cuando el valor del elemento vale 6, entonces quedará {1, 2, 3, 4, 5, 7}.
ACTUALIZACIÓN DE VARIABLES
datos[N] = {1, 2, 3, 4, 7}
referencia = 6
El último for es el que itera datos para mostrar elemento a elemento por pantalla. Este será el resultado final.
Respuesta: 12347.