Temas:
Es importante conocer estos patrones de programación porque son muy útiles para concebir nuevos programas. Ellos resuelven problemas conocidos sin tener que re-inventar soluciones para esos problemas una y otra vez.
Un ejemplo de estos patrones de programación es la acumulación. Este patrón se usa para realizar cálculos como la suma de varios valores calculados en las iteraciones de un ciclo:
La forma general de este patrón es:
La variable utilizada en este patrón se denomina acumulador.
``tipo'' ``variable'' = ``valor inicial'';
...
while ( ... ) {
...
``variable'' = ``variable'' ``operador'' ``expresión'';
...
}
Ejemplos:
? 4.0
? 5.0
? 6.0
? 0.0
Contador= 3
Observe la similitud de esta solución con la que calcula
la suma de las notas.
int cont= 0; double suma= 0.0;
double nota;
print("? ");
nota= readDouble();
while (nota!=0.0) {
cont= cont+1; suma= suma + nota;
print("? ");
nota= readDouble();
}
print("Contador= "); print("Suma= ");
println(cont); println(suma);
? 4.0
? 5.0
? 6.0
? 0.0
Promedio= 5.0
En este programa se presenta también el patrón de lectura de datos. Su
forma general es:
double suma= 0;
int cont= 0;
double nota;
print("? ");
nota= readDouble();
while (nota!=0.0) {
suma= suma+nota;
cont= cont+1;
print("? ");
nota= readDouble();
}
print("Promedio= ");
println(suma/cont);
Típicamente marcaremos el fin de los datos con un cero o -1.
``tipo'' ``variable'';
...
``variable''= read``tipo''();
while ( ... ) {
...
``variable''= read``tipo''();
}
? 4
1
2
3
4
Acá, el programa termina cuando la variable i excede en valor a n.
En realidad, estamos acá en presencia de otro patrón muy utilizado:
el patrón de conteo. Este patrón constituye un caso particular
del patrón de acumulación. Su forma general es:
print("? ");
int n= readInt();
int i= 1;
while (i<=n) {
println(i);
i= i+1;
}
La variable i se denomina en este caso un contador y toma valores
entre [``valor inicial'',``valor final''], incrementándose en 1 en
cada iteración.
int i= ``valor inicial'';
while ( i <= ``valor final'' ) {
...
i= i + 1;
}
Definición matemática:
O informalmente:
Solución: al programa anterior le agregamos el producto de los valores sucesivos que toma la variable i en cada iteración. Para hacer el cálculo usamos el patrón acumulación con el operador *.
print("? ");
int n= readInt();
double fact= 1.0;
int i= 1;
while (i<=n) {
fact= fact*i;
i= i+1;
}
print("El factorial es ");
println(fact);
Ejecute paso a paso el programa anterior. Suponga que el usuario ingresa el número 3.
Ejercicio 2:
Calcular exp(x) por medio de la siguiente aproximación.
Solución:
El siguiente programa calcula i! al mismo tiempo que calcula x^i.
Observe que en la i-ésima iteración, la variable xi es x^i
y facti es i!.
double xi= 1.0;
double facti= 1.0;
int i= 1;
while (i<=n) {
xi= xi*x;
facti= facti*i;
i= i+1;
}
A este programa podemos agregarle una acumulación de xi/facti:
Ahora basta desplegar el resultado final con la instrucción:
double x= ...; // Obtener x y n
int n= ...;
double xi= 1.0;
double facti= 1.0;
double expx= 1.0;
int i= 1;
while (i<=n) {
xi= xi*x;
facti= facti*i;
expx= expx + xi/facti;
i= i+1;
}
println(expx);
Ejercicio 3:
Haga un programa que lea varios números positivos (terminados con un -1) e indique en qué rango se encontraban (exceptuando el -1). El diálogo debe ser:
? 5
? 3
? 20
? 10
? -1
El rango es [3,20]
Observe que las instrucciones que están en negritas corresponden
a una variación del patrón de acumulación. No es exactamente
el patrón de acumulación, pero se asemeja. Si hubiésemos escrito:
int num;
int max;
int min;
print("? ");
num= readInt();
max= num;
min= num;
while (num!=0) {
if (num>max) max= num;
if (num<min) min= num;
print("? ");
num= readInt();
}
print("El rango es [");
print(min); print(",");
print(max); println("]");
sería aún más parecido. El operador del patrón de acumulación sería en
este caso max.
max= max(max,num);
El programa también se puede escribir como:
Ejecute paso a paso dos iteraciones de este programa y se
convencerá de que está correcto. MAXINT es una constante entera
que es más grande que cualquier otro entero en Java.
int num;
int max= 0; // o MININT
int min= MAXINT;
print("? ");
num= readInt();
while ( ... ) { ... }
...
En realidad, los enteros en Java tienen un valor máximo (y un mínimo para los negativos). El primer número que se lea forzosamente será menor (o igual) a MAXINT y quedará por lo tanto almacenado en min ya en la primera iteración.