Que son los sumadores o acumuladores?

Ya conociendo el uso del los contadores, podremos comprender fácilmente el concepto de Sumador o Acumulador. Los sumadores o acumuladores son tambien variables, pero su uso no es el mismo pues se usan para acumular valores. Por ejemplo, si quisiéramos saber cual es la suma de todos los números del 1 al 100, debemos ir desde 1 hasta 100 y en cada paso del ciclo, sumarle a una variable. Esta sería el sumador, los valores que irá tomando el contador en cada caso.

1+2+3+4+5 +(..) +100 = 5500.

Ya sabemos cual es el resultado que nos debe imprimir el programa, 5500 gracias a Euler, pero de igual forma vamos a programarlo.

Programa #11

Int s = 0;
Desde(int i = 1;i<=100;i++) {
   s += i    
}
Imprimir (“Desde 1 hasta 100, la suma es de: ” . s);

La variable “s” representa al sumador, y la variable “i” al contador. Ya conoces que en cada paso del ciclo (que en este caso serían 100 pasos) la variable “i” tomará automáticamente valores incrementándose en 1. Con el sumador estamos “capturando” esos valores y sumándoselos a el mismo para despues imprimir (al final de ciclo) el valor final.

Multiplicadores

Lo multiplicadores son exactamente lo mismo que los sumadores, la única diferencia es que las operación que utilizamos con ellos es la multiplicación en lugar de la suma. Vimos el ejemplo de sumar todos los números del 1 al 100, e ir guardando los valores en un contador anteriormente. Pero si lo que queremos es multiplicar? Entonces entran en juego los multiplicadores y el mejor ejemplo para dejarlo claro es El concepto de factorial.

Como se calcula el factorial?

El factorial de un número se calcula multiplicando al número mismo con su antecesor, con el antecesor de su antecesor, y así sucesivamente hasta llegar a 1. El signo que se usa para el factorial en matemáticas es “!”, y el factorial de 5 por ejemplo se escribe así “!5”. Esta expresión significa multiplicar 5*4*3*2*1. Como resultado da 120, muy fácil, pero si quisiéramos hacer un programa que calcule el factorial de cualquier número entero entrado por el teclado, ¿Cómo lo haríamos?

Primero, debemos pedirle al usuario que nos entre un número entero, después, de guardar el número en una variable, tendríamos que crear un ciclo simple, que comience en el número que entramos por teclado, y termine en 1, y en cada paso del ciclo, que nuestro multiplicador se encargue de guardar los valores las multiplicaciones correspondientes.

Programa #12 (Calculo del factorial utilizando iteraciones y sumadores)

Int numero;
Int factorial = 1;
Imprimir (“Entre el numero para calcular factorial:”);
Leer numero;

Desde (int i = numero;i>1;i--) {
   Factorial = factorial * i;
}

Imprimir (“!”. numero . “ = ” . factorial);

Como resultado, este programa daría, en caso de que entremos un 5 por teclado:

!5 = 120

Que es un ciclo invertido?

En este ejemplo vemos un ciclo invertido. Este tipo de ciclo itera desde un número mayor hasta un número menor. En los casos anteriores habíamos visto ciclos en los que se comenzaba en 1 y se terminaba en 100, o en 10 o en 15, siempre un numero mayor, en este caso, si el usuario entra por teclado un 5, el ciclo recorrerá desde 5 hasta 1, dando en la variable “i” los valores 5,4,3,2,1 respectivos a cada paso de la iteración. Lo pudiéramos hacer con un ciclo no invertido, y daría el mismo resultado pues 5*4*3*2*1 es igual a 1*2*3*4*5. Pero hay ocasiones en los que este tipo de ciclo les será muy útil. Su característica principal es que el contador no se incrementa, sino que se decrementa, como lo expresa “i–”.

Explicacion algoritmo factorial

El ciclo comienza en el valor que el usuario entre por teclado. Desde ese valor hasta 1, serán las veces que se va a ejecutar su bloque de código. La condición de parada expresa que el ciclo se va a repetir mientras que el valor de “i”  cumpla la condición “i>1”. Para que el contador no sea mayor que 1, debe, necesariamente, ser menor o igual que 0. Ni los números menores que el cero ni el cero mismo nos interesan, pues no entran en la definición del factorial.

El bloque de código, que en este caso es una sola instrucción, hace uso del decremento de la variable contadora para “capturar” su valor y multiplicárselo al valor que tenga en ese momento el factorial. Fíjese que la variable “factorial”  fue inicializada en 1, pues de inicializarla en cero, produciría un cero como resultado final (multiplicacion por cero). El multiplicador “factorial” ira guardando en cada paso el valor de la multiplicación de el mismo y el contador. Terminado el ciclo, la variable “factorial” queda disponible para imprimir el resultado de la operación.

Los sumadores, multiplicadores y los contadores tienen diversos usos. Estos ejemplos sencillos no resuelven ningún problema real, el verdadero problema que resuelven es que seas capaz de dominarlos y comprenderlos. Cuando eso suceda, serás capaz de formularte verdaderos problemas y resolverlos.

Estructura Iterativa “Mientras”

Ya conociendo de que se tratan los contadores, sumadores y multiplicadores, podemos continuar con el estudio de otras estructuras iterativas, o de control. La siguiente estructura iterativa recibe el nombre, en muchos lenguajes de programación de While, en nuestro pseudocódigo la llamaremos Mientras. 

Diferencias entre estructuras iterativas «Desde» y «Mientras»

Su principal diferencia con la estructura iterativa Desde, es que la variable contadora no se incrementa automáticamente, tenemos que incrementarla nosotros dentro del bloque de código. Con la estructura Desde, sabíamos de antemano cuantas veces se iba a repetir el bloque de código que contiene, en cambio en la estructura Mientras podemos o no saber cuantas veces se va a ejecutar.

Supongamos que queremos optimizar el programa Calculadora, que resolvimos en los primeros capítulos. Cuando procedíamos a calcular una división, era necesario que el usuario no entrara un valor de cero, para el dividendo, pues caeríamos en indefinicion matematica. La solución que le dimos a ese problema fue muy sencilla porque no conocíamos esta estructura iterativa.

Explicando la estructura iterativa «Mientras» y como puede optimizar nuestro codigo

Si el usuario entraba un cero como dividendo, utilizando una estructura condicional Si, impedíamos que se realizara la operación de división, y se terminaba el programa. Pero ¿si quisiéramos que el programa pidiera el dividendo una y otra vez hasta que el usuario no entre un cero? Utilizando este tipo de ciclo, podemos resolver ese problema.

Ejemplo 1

Int n2 = 0;

Mientras (n2 == 0) {

   Imprimir (“Teclee el segundo numero ”);
   Leer n2;

   Si(n2 == 0) entonces {
      Imprimir (“No se permite un 0 como dividendo”);
   }

}

El ejemplo 1, garantiza que el programa pida el segundo numero y lo guarde en la variable n2 una y otra vez, en cada caso, si se entra un cero, se imprimirá un mensaje explicando que no se admiten ceros, tal y como dice la instrucción Si. Ahora analicemos. Se inicializa la variable n2 con el valor de cero, con el objetivo de “Engañar” a la estructura Mientras, pues su haciendo esto estamos satisfaciendo su condición de continuación “n2 = = 0”

O sea, siempre que n2 sea cero el bucle se va a repetir, y dejara de hacerlo cuando n2 no tome un valor de cero, o sea, “n2 = = 0” no se cumpla. La única forma de entrarle valores a n2 sería por teclado. Si no hubiéramos inicializado n2 en cero, la primera repetición del ciclo no se hubiera ejecutado.Esto es debido a que n2 no tendría el valor de cero y hubieramos tenido que haber escrito el mensaje de Teclear segundo numero y “Leer n2” para que la variable n2, tuviera un valor definido antes de que la estructura repetitiva Mientras, se pregunte ¿n2 es igual a cero?. Inicializar n2 en cero, es una buena práctica de programación, pues ahorra código, y evita redundancias. Ahora expliquemos como funciona el ciclo.

Estructura «Mientras» dentro del compilador, como funciona

El ciclo Mientras antes de ejecutar el bloque de código se pregunta si n2 es igual a cero. En el primer paso n2 vale cero pues lo inicializamos antes del ciclo intencionalmente. Como n2 es cero y es un valor inválido para nuestro programa de división, se pide que se entre por teclado el segundo número y se guarda en n2. Supongamos que el usuario se equivoca y entra un cero por teclado.

Rápidamente la estructura condicional se encarga de imprimir un mensaje de error. Cuando se llega al final del bloque de código el ciclo vuelve a repetirse, y antes que todo se vuelve a preguntar ¿es n2 igual a cero? Ya vimos que el usuario tecleo un cero y este se guardó en n2, por tanto n2 vale cero. Siendo así,  se vuelve a repetir el bloque de código comenzando por Imprimir un mensaje que pide el segundo número.

Ya el usuario fue advertido con el mensaje de error proporcionado por la condicional Si. En este momento lo lógico sería que el entrara un valor diferente de cero. Supongamos que entro un 5, este 5 se guarda en n2 gracias a la instruccion Leer n2. Continua el bloque de código con la condicional Si, la cual se pregunta ¿es n2 igual a cero? Evidentemente no pues en este paso nuestro consciente usuario entro un 5, por lo que n2 vale 5.

El bloque de código termina y el Mientras vuelve a preguntarse ¿es n2 igual a cero? No, n2 vale 5, por tanto en el preciso instante que su condición de continuidad no se cumple se rompe el ciclo. Sucedido esto, el control pasa a la siguiente instrucción despues del ciclo.

Ahora veamos un ejemplo en el que usaremos contadores con la estructura Mientras.  En los programas que se necesite usar contadores, generalmente se puede usar cualquiera de las dos estructuras iterativas previamente estudiadas.

Problema del promedio, utilizando iteracion «Mientras»

Realicemos un programa que primero pida la cantidad de números que vamos a entrar, después los vaya pidiendo 1 a 1 y al final nos calcule el promedio de esos números.

Para esto vamos a usar una variable para guardar la cantidad de números con los que vamos a calcular el promedio. Esta variable puede ser Int, aunque no necesariamente. También necesitamos un sumador para ir acumulando los valores que se vayan entrando en casa paso, y un contador para controlar el ciclo. Además necesitaremos de una variable para guardar la nota que el estudiante entra por teclado y por ultimo, una variable para guardar el promedio.

Es evidente que necesitamos un ciclo pues no sabemos la cantidad de números que el usuario necesita usar para el promedio. Puede que un estudiante de secundaria necesite calcular el promedio de sus notas en matemáticas (que serían 4 notas), incluyendo la final, pero puede que ese mismo estudiante necesite calcular su promedio general de todas las asignaturas. El ciclo que usaremos sería un Mientras, aunque también lograríamos el mismo resultado con un Desde.

Programa #13

Int Cant = 0;
Float Promedio;
Int Sumador = 0;
Int Nota;
Int i = 1;

Imprimir (“Entre la cantidad de notas a calcular”);
Leer Cant;

Mientras(i <= Cant)
{
   Imprimir (“Entre la Nota # ” . i);
   Leer Nota;
   Sumador += Nota;
   i++;
}

Promedio = Sumador / Cant;
Imprimir (“El promedio de las notas es ” . Promedio . “ puntos.”);

El programa produciría la siguiente salida.

Entre la cantidad de notas a calcular
5


Entre la Nota # 1
20


Entre la Nota #2
20


Entre la Nota #3
30


Entre la Nota #4
40


Entre la Nota #5
10


El promedio de las notas es 24 puntos.

Explicacion del problema #13

Ahora expliquemos el código. Primero se declaran e inicializan las variables necesarias para la resolución del problema. Después se le pide al usuario que entre la cantidad de notas que va a entrar por teclado. Esta cantidad se guarda en la variable Cant  y su valor tiene dos propósitos. El primero, como máximo numero de repeticiones del ciclo que va pidiendo los valores de las notas.El segundo, para el cálculo del promedio.

En el paso siguiente es el ciclo quien tiene la función de pedirle al usuario tantas notas como indique Cant, además de irlas sumando a la variable Sumador. Esta ultima tendrá disponible en el momento en que rompa el ciclo, la suma de todas las notas entradas por teclado. Esto se nota con la instrucción Sumador += Nota. Dentro del mismo ciclo vemos como es el incremento de la variable contadora “i” quien tiene como función llevar una cuenta de cuantas veces se ha ejecutado dicho ciclo. Terminado el ciclo tenemos en la variable Cant la cantidad de notas que se han entrado. Ademas en Sumador tendremos la suma de todas las notas. El promedio ya se puede calcular con estos datos, y más tarde imprimirlo por pantalla dándole solución al problema.

Problema del promedio sin usar contador

Ahora veremos otro ejemplo del uso del ciclo Mientras, pero esta vez sin un contador. El problema a resolver es el mismo, aunque vamos a usar otro método para controlarlo. Este método, le da la posibilidad al usuario de ir entrando los valores de las notas sin necesidad de especificarlo al principio del programa. La forma de hacerlo será ir leyendo los valores de las notas hasta que el usuario entre un -1. Esto significará que el usuario quiere terminar la fase de entrar datos, entonces procederemos de igual forma al ejercicio anterior. Ten en cuenta que hay un ligero cambio en las variables que usaremos aquí.

Programa #14

Int Cant = 1;
Float Promedio;
Int Sumador = 0;
Int Nota = 0;

Mientras (Nota != -1) {
 Imprimir ("Entre la nota # " + Cant);
 Leer Nota;

 Si (Nota != -1) {
     Sumador += Nota;
      ant++;
   }
}

Promedio = Sumador / (Cant-1);
Imprimir (“El promedio de las notas es " . Promedio);

Explicacion del problema #14

Primero veamos las variables. Observa que la variable Cant pierde uno de sus roles con respecto al ejemplo anterior. En este ejemplo solo se usa para conocer la cantidad de notas que se han entrado. Su función de detener el ciclo ya no es necesaria aquí, pues el método para controlar el ciclo esta basado ahora en la variable Nota. 

Se inicializa en uno para cuando el programa vaya pidiendo las notas, ir teniendo en cada una de las iteraciones el valor de notas que se ha entrado hasta el momento. Así podremos imprimir el mensaje de petición de una forma más eficiente, aunque esto traerá problemas más adelante. Todas las demás variables las inicializamos en cero.

El ciclo Mientras tiene en su condición de parada la siguiente expresión lógica Nota ¡ = -1. Esta expresion pregunta si la variable Nota, quien en el ejemplo anterior solo estaba destinada a guardar la nota entrada por teclado, es desigual a -1. Lógicamente las notas de las asignaturas cualesquiera que sean no son negativas, y aprovechando eso utilizamos un valor -1 en Nota para terminar el ciclo. O sea, en el preciso instante en que el usuario teclee un -1 como nota, el programa entenderá que ya el usuario no desea entrar mas notas y procederá a calcular el promedio.

Como inicializamos Nota en 0 la primera iteración del ciclo se ejecuta, pues no se cumple la condición de parada. Siendo así, se imprime el mensaje de petición al usuario. El usuario teclea su nota y se guarda en la variable Nota , sespués nos encontramos con la condicional Si, quien pregunta si la nota entrada es -1. Esta condicional tiene una función primordial en nuestro ejemplo pues suponiendo que el usuario halla entrado un -1 y quiere dejar de entrar datos, esta impide que pase al Sumador el valor -1 como nota.

O sea, nuestra condicional hace función de filtro solo cuando el valor entrado en Nota sea una nota verdadera y no el -1.

Lo mismo sucede con la variable Cant, quien intencionalmente esta dentro de la condicional. Como Cant lleva la cuenta de cuantas notas se han entrado por teclado,  no nos conviene que al entrar un -1 se tome como que es una nueva nota. Entonces supongamos que el usuario no entró un -1 como Nota, el ciclo termina su primer paso y verifica en su condición de parada si en Nota hay un -1.

Como no es el caso, continúa, y así sucesivamente hasta que el usuario entre un -1. Cuando esto sucede, nuestro Si al preguntarse si Nota ¡= -1 se responde que no, por tanto no ejecuta lo que hay dentro de su bloque de código. Y el ciclo termina este paso. Cuando va a ejecutar el otro, su condición de parada detecta que la expresión lógica Nota ¡= -1 no se cumple, por tanto se rompe el ciclo y pasa a calcular el promedio. En el cálculo del promedio, vemos que:

Promedio = Sumador / (Cant-1). Esta es la consecuencia de lo que habíamos hablado anteriormente. Como Cant se inicializó en 1 para poder imprimirle al usuario Entre la nota # 1; a la hora de calcular el promedio esta variable va a contener la cantidad de veces que entramos notas por teclado incrementado en 1. Si hubiera sido inicializada en cero esto no hubiera pasado, pero hubiéramos tenido que imprimir como primer mensaje Entre la nota # 0, lo cual no es muy intuitivo. Esto es porque siempre debemos pensar primero en el usuario y después en nuestras comodidades. Por eso es que en el calculo del promedio decrementamos Cant  en 1, para asegurar que el promedio sea el correcto. Después se imprime el mensaje del resultado y fin del problema.

El programa produciría la siguiente salida.

Entre la Nota # 1
20


Entre la Nota #2
20


Entre la Nota #3
30


Entre la Nota #4
40


Entre la Nota #5
10


Entre la Nota #6
-1


El promedio de las notas es 24 puntos.

sumadores o acumuladores

Cualquiera de los dos ejemplos descritos anteriormente le da respuesta al problema inicial. Queda a tu disposicion escoger el más conveniente.