470 likes | 803 Views
Estructuras de repetición. Programación Básica. Motivación. Suponga que se desea sumar una lista de 20 números y obtener el promedio. Sin estructuras de repetición habría que escribir 20 sentencias de entrada. Algo como: int n,suma = 0; cout << “tecle n: “; cin >> n; suma = suma + n;
E N D
Estructuras de repetición Programación Básica
Motivación Suponga que se desea sumar una lista de 20 números y obtener el promedio. Sin estructuras de repetición habría que escribir 20 sentencias de entrada. Algo como: int n,suma = 0; cout << “tecle n: “; cin >> n; suma = suma + n; Repetir las tres últimas sentencias 19 veces, o bien definir veinte variables diferentes y escribir un código como el siguiente. int n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16, n17,n18,n19,n20, suma = 0; cout << “teclee los 20 valores “; cin >> n1 >> n2 >> n3 >> n4 >> n5 >> n6 >> n7 >> n8 >> n9 >> n10 >> n11 >> n12 >> n13 >> n14 >> n15 >> n16 >> n17 >> n18 >> n19 >> n20; suma = n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8 + n9 + n10 + n11 + n12 + n13 + n14 + n15 + n16 + n17 + n18 + n19 + n20;
Ambas soluciones son posibles. Sin embargo si el número de valores que se deben sumar es diferente, habrá que modificar cualquiera de ellos para obtener una solución adecuada. Además si el número de valores a sumar es muy grande, programa se hace prohibitivamente grande. Por lo anterior vemos que debe existir otra alternativa para resolver este tipo de problemas. La solución nos la dan las instrucciones de repetición. Primero revisaremos la sentencia while.
Ciclo while La sentencia while permite repetir un bloque de instrucciones. La sintaxis del ciclo while es: while(condición) sentencia o bloque; Si la condición se cumple se ejecutan las sentencias del bloque y se regresa el flujo de control a evaluar nuevamente la condición. El proceso se repite hasta que la condición sea falsa. El ciclo puede ejecutarse 0 veces si la condición no se cumple al entraren él. verdadero condición sentencias falso
Ejemplo Cálculo de el promedio de 10 números. #include <iostream.h> #include <conio.h> int main(){ float suma = 0.0, num, promedio; int contador = 0; while(contador < 10){ cout << "Teclee un número:"; cin >> num; suma = suma + num; contador = contador + 1; } promedio = suma/contador; cout << "\nEl promedio es: " << promedio << endl; getch(); }
ciclo controlado por centinela Cálculo de el promedio de N números. Se utiliza un valor especial para detener la entrada de datos. int main(){ float suma = 0.0, num, promedio; int contador = 0; cout << "Teclee un número (-1 = fin):"; cin >> num; while(num != -1){ suma = suma + num; contador = contador + 1; cout << "Teclee un número (-1 = fin):"; cin >> num; } if(contador>0){ promedio = suma/contador; cout << "\nEl promedio es: " << promedio << endl; } else cout << "\nNo se teclearosn valores" << endl; getch(); }
Operadores de asignación En C existen operadores para abreviar las operaciones de asignación. Por ejemplo: c = c + 3 puede escribirse como c += 3. En general variable = variable operador expresión es equivalente a variable operador= expresión Ojo a *= c + d equivale a a = a*(c + d) no a = a*c + d
Ejemplo sobre números primos Un problema típico de ciclos es la determinación si un número es primo o no. Un número es primo si es divisible solo por la unidad y por si mismo. Para saber si un número es primo debemos dividirlo entre todos sus posibles divisores. No es necesario verificar la divisibilidad de un número para todos los números menores que el, basta con verificar con números que sean menores o iguales a su raíz cuadrada, dado que el divisor más grande que puede tener un número es su raíz cuadrada.
Algoritmo primo Proceso NumeroPrimo Escribir "Tecle un numero"; Leer numero divisor<-2 primo<-1 Mientras divisor<=raiz(numero) y primo=1 Hacer si (numero mod divisor)=0 Entonces primo<-0 FinSi divisor<-divisor+1 FinMientras si primo=1 Entonces Escribir "Si es primo" Sino Escribir "No es primo" FinSi FinProceso
Determinación de número primo #include <iostream> Using namespace std; int main(){ int divisor = 2, numero, primo = 1; cout << "Teclee un número > 2: "; cin >> numero; while(n <= sqrt(numero) and primo){ if(num % divisor == 0)//es divisible entre divisor primo = 0; divisor++; } if(primo) cout << "\nEl número " << num << " es primo\n"; else cout << "\nEl número " << num << " NO es primo\n"; system(“pause”); }
Ciclos anidados Una instrucción de ciclo puede estar contenida dentro de otra instrucción de ciclo. El siguiente algoritmo despliega un rectángulo de 10x5 de ‘*’ Proceso ciclosAnidados renglon<-0 Mientras renglon<5 Hacer columna<-0 Mientras columna<10 Hacer Escribir sin saltar "*" columna<-columna+1 FinMientras Escribir "" renglon<-renglon+1 FinMientras FinProceso
Cuadro en C #include <iostream> using namespace std; main(){ int renglon, columna; renglon=0; while(renglon<5){ columna=0; while(columna<10){ cout <<'*'; columna++; } cout<<endl; renglon++; } system("pause"); }
Actividad Escriba un programa que lea un número desde el teclado y dibuje un triángulo como se muestra a continuación con un número de renglones igual al número leído. Por ejemplo, si el número leído es 6, el resultado será: *********************
Encontrar primos entre 1 y 100 Para desplegar los números primos entre 1 y 100 hacemos un ciclo anidado que tenga como ciclo interno el algoritmo para determinar si un número es primo y como ciclo externo un ciclo que recorra todos los número de 2 a 99. Un esbozo de algoritmo es el siguiente Ciclo con número de 2 a 99 ciclo verificar si el número es primo fin de ciclo si es primo imprimir numero Fin de ciclo
Algoritmo Proceso primos1a100 numero<-2 Mientras numero<100 Hacer divisor<-2 primo<-1 Mientras divisor<=raiz(numero)y primo=1 Hacer si (numero mod divisor)=0 Entonces primo<-0 FinSi divisor<-divisor+1 FinMientras si primo=1 Entonces Escribir Sin Saltar numero," " FinSi numero<-numero+1 FinMientras FinProceso Ciclo interno Ciclo externo
Determinar los primos de 1 a 100 int main(){ int n, num = 2, esPrimo, limite; while(num<=100){ esPrimo = 1; n = 2; limite = (int)sqrt(num); while(n <= limite && esPrimo){ if(num % n == 0) //es divisible entre n esPrimo = 0; n++; } if(esPrimo) cout << num << " "; num++; } getch(); return 0; } lazo interno lazo externo
Actividad Escriba un programa para encontrar todos los divisores de un número. Un número es perfecto si es igual a la suma de sus divisores, por ejemplo 6 es perfecto porque 6 = 1 + 2 + 3. Escriba un programa para encontrar todos los números perfectos entre 1 y 10000.
Ciclo for La sentencia for permite definir fácilmente ciclos controlados por contador. El formato general de la estructura for es: for(expresion1; expresion2; expresion3) instrucción; Esta es equivalente a la siguiente sentencia while: expresion1; while(expresion2){ instrucción; expresion3; } expresion1 = sentencia de iniciación expresion2 = condición de terminación expresion3 = sentencia de incremento
ejemplos de lazos for a) modifica la variable de control de 1 a 100 en incrementos de 1. for(i = 1; i <= 100; i++) b) modifica la variable de control de 100 a 1 en decrementos de 1. for(i = 100; i >= 1; i--) c) modifica la variable de control de 7 a 77 en incrementos de 7. for(i = 7; i <= 77; i += 7) d) modifica la variable de control de 20 a 2 en decrementos de -2. for(i = 20; i >= 2; i -= 2) e) modifica la variable de control de 2 a 20 en incrementos de 3. for(i = 2; i <= 20; i += 3) f) modifica la variable de control de 99 a 0 en decrementos de -11. for(i = 99; i >= 0; i -= 11)
Cálculo de intereses Se requiere calcular los intereses de una cuenta de ahorro en la que se deposita un cierto capital. Los intereses se acumulan año con año y el capital se deja en el banco un cierto número de años. El programa que se desea leerá el monto del capital, el número de años y la tasa de interés anual. El monto total del capital más intereses se calcula con la fórmula: total = capita(1+tasa)años Se desea que el programa imprima el monto total al final de cada año.
Algoritmo Proceso interes Escribir "Capital a depositar" Leer capital Escribir "Numero de años" Leer anyos Escribir "tasa de interés (en%)" Leer tasa Para a desde 1 Hasta anyos total<-capital*(1+tasa/100)^a Escribir "año ",a," Total=",total FinPara FinProceso
Cálculo de interés compuesto #include<iostream> #include<cmath> using namespace std; int main() { float capital,tasa,total; int a,anyos; cout<<"Capital a depositar"<<endl; cin>>capital; cout<<"Numero de años"<<endl; cin>>anyos; cout<<"tasa de interés (en%)"<<endl; cin>>tasa; for (a=1;a<=anyos;a++) { total=capital*powf(1+tasa/100,a); cout<<"año "<<a<<" Total="<<total<<endl; } system("pause"); }
Suma de series Es común el tener que sumar series de valores. Por ejemplo: La serie anterior es igual a p. Para evaluar una serie iniciamos la suma con el primer término. Si la serie tiene signos alternantes, como la de arriba, se utiliza una variable (que puede ser entera) con valor 1 si el segundo término es positivo o -1 si es negativo, para multiplicar el término actual. Luego se ejecuta un lazo for para sumar cada término y se cambia el signo de la variable que retiene el signo, para esto se utiliza la instrucción signo = -signo;
algoritmo Proceso valor_de_pi suma<- 4 signo<- -1 para i Desde 1 Hasta 100 suma<-suma+signo*4.0/(2.0*i+1) signo<- -signo FinPara Escribir suma FinProceso
actividad Escriba programas para evaluar las siguientes series.
Suma de series Una serie de potencias en x requiere del cálculo de la potencia de la variable en cada término. Esto puede hacerse iniciando antes del ciclo una variable potencia a 1 y multiplicando a cada paso esta variable por x. Estos es potencia = 1; inicio del lazo potencia = potencia*x; actualizar la suma fin del lazo
Serie de potencias Evaluemos la serie de potencias del seno de un ángulo Se requiere una variable para almacenar la potencia de x, otra para el factorial y otra para el signo. seno = x; signo = -1; fact = 1; pot = x; for(int i = 3; i <=50 ; i +=2){ fact *= (i-1)*i; pot *= x*x; serie += signo*pot/fact; signo = -signo; }
Tarea #6 Escriba un programa que lea un ángulo en grados y calcule el coseno del ángulo utilizando la serie de potencias
Ciclo do - while El ciclo do-while es similar al ciclo while excepto que la prueba se realiza al final del ciclo, esto fuerza a que se ejecute por lo menos una vez. Sintaxis do{ sentencias; }while(condición); sentencias condición verdadero falso
Equivalencia while, do-while El ciclo do-while do{ sentencias; }while(condición); Es equivalente al ciclo while sentencias; while(condición) sentencias;
ciclo do-while controlado por centinela Cálculo de el promedio de N números. Se utiliza un valor especial para detener la entrada de datos. int main(){ float suma = 0.0, num, promedio; int contador = 0; do{ cout << "Teclee un número (-1 = fin):"; cin >> num; if(num != -1){ suma = suma + num; contador = contador + 1; } }while(num != -1); if(contador>0){ promedio = suma/contador; cout << "\nEl promedio es: " << promedio << endl; } else cout << "\nNo se teclearosn valores" << endl; getch(); }
Método de Newton-Raphson Se pretende encontrar el valor de x donde una función se hace cero. La ecuación de la recta tangente es: y – f(xn) = f ’ (xn)(x – xn) Cuando y = 0, x = xn+1 o sea 0 – f(xn) = f ’ (xn)(xn+1– xn) o f(x) Pendiente = f ’ (xn) f (xn) xn+1 xn
Algoritmo Newton Para obtener una solución a f(x) = 0 dada una aproximación p0. ENTRADA aproximación inicial p0; tolerancia tol; número máximo de iteraciones N0. 1. i = 1 2. Mientras i<=N0 hacer 2.1. p = p0 – f(p0)/f’(p0) 2.2. Si |p – p0|< tol entonces regrese p 2.3. i = i + 1 2.4. p0 = p 3. fracaso en encontrar la raíz en N0 iteraciones
Método de newton Se desea calcularla raíz de la ecuación sen(x) – e-x = 0 por el método de Newton. #include <iostream> #include <cmath> using namespace std; int main() { double x, xOld, fx, dfx; x = 0.5; do{ xOld = x; fx = sin(x)-exp(-x); dfx = cos(x)+exp(-x); x = xOld - fx/dfx; cout << "fx = " << fx << " dfx = " << dfx << " x = " << x << endl; }while(fabs(fx)>1e-6); cout << "raiz = " << x << endl; system(“pause”); }
Resultado del método de Newton fx = -1 dfx = 2 x = 0.5 fx = -0.127105 dfx = 1.48411 x = 0.585644 fx = -0.00401128 dfx = 1.3901 x = 0.588529 fx = -4.62025e-006 dfx = 1.3869 x = 0.588533 fx = -6.16098e-012 dfx = 1.3869 x = 0.588533 raiz = 0.588533
Validación Una aplicación común del ciclo do-while es en la validación de valores de entrada, es decir, cuando se requiere restringir el conjunto de valores que el usuario debe introducir para garantizar el buen funcionamiento de un programa. El algoritmo de validación puede resumirse en los siguientes pasos: Algoritmo de validación: 1. Hacer ciclo 2. Leer datos 3. Mientras datos inválidos
Ejemplo #include <iostream>usingnamespace std;main(){int a,b;do{ cout << "Teclee un número positivo para A: "; cin >> a; }while(a<=0);do{ cout << "Teclee un número positivo para B: "; cin >> b; }while(b<=0); cout << "a * b = " << a*b; cin.get();}
Ejemplo de validación de una fecha Para validar una fecha debemos asegurar que los días caigan en el intervalo de 1 a 31 y los meses de 1 a 12. Una mejora consiste en verificar los días de acuerdo con el mes. Para febrero en año bisiesto el máximo de días es 29 en otro caso es 28. Supondremos la declaración de las siguientes variables de tipo entero: a, m, d, anyoBisiesto, mes30dias, mes31dias y fechaValida. Para verificar si el año bisiesto usamos la siguiente expresión booleanas: anyoBisiesto = (a%4==0)&&(a%100!=0); Para verificar los meses de 30 y 31 días: mes30dias = (m==4 || m==6 || m==9 || m==11); mes31dias = (m==1||m==3||m==5||m==7||m==8||m==10||m==12);
Una expresión para validar fecha debe ser verdadera si el número de días es menor o igual a 30 y el mes es de 30 días o si el número del día es menor o igual que 31 y el mes es de 31 días o si el número del día es menor o igual a 28 y el mes es febrero o si el número del día es menor o igual a 29 y el mes es febrero y es año bisiesto. Esto puede escribirse en C como: fechaValida = (d<=31 && mes31dias)||(d<=30 && mes30dias)|| (d<=28 && m==2)||(d<=29 && anyoBisiesto && m==2);
Programa #include <iostream> using namespace std; main(){ int d,m,a;//día, mes, año int anyoBisiesto,mes30dias,mes31dias,fechaValida; do{ cout <<"Teclee una fecha (dd mm aa): "; cin >>d>>m>>a); anyoBisiesto = (a%4==0)&&(a%100!=0); mes30dias = (m==4 || m==6 || m==9 || m==11); mes31dias = (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12); fechaValida = (d<=31 && mes31dias)|| (d<=30 && mes30dias)||(d<=28 && m==2)||(d<=29 && anyoBisiesto); }while(!fechaValida);
cout <<d<<" de "; switch(m){ case 1: cout<< "enero";break; case 2: cout<<"febrero";break; case 3: cout<<"marzo";break; case 4: cout<<"abril";break; case 5: cout<<"mayo";break; case 6: cout<<"junio";break; case 7: cout<<"julio";break; case 8: cout<<"agosto";break; case 9: cout<<"septiembre";break; case 10: cout<<"octubre";break; case 11: cout<<"noviembre";break; case 12: cout<<"diciembre";break; } cout<<" de “<<a<<endl; cin.get(); }
Tarea #7 Resuelva la siguiente ecuación con el método de Newton x3 – 2x2 +3x +1 = 0 Escriba un programa que lea un número entero y calcule el factorial de ese número. Calcule el factorial utilizando un lazo for, un lazo while y un lazo do-while. Escriba un programa que despliegue el triángulo de Pascal definido por (ayuda: utilice la fórmula de combinaciones de n elementos tomados de k en k) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 etc