Arreglos Programacin Bsica Definicin Un arreglo es una
Arreglos Programación Básica
Definición Un arreglo es una colección de elementos del mismo tipo que se reconocen por un solo identificador. Para acceder a los elementos individuales de un arreglo se utiliza un subíndice que debe ser un número entero. Arreglo con nombre a a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] 56 56 91 0 -3224 100 62 12 Número de la posición de cada elemento
Ejemplo: mayor puntaje El siguiente programa calcula el mayor puntaje de grupo de puntos y la diferencia de cada puntaje y el más alto: #include <iostream> using namespace std; main(){ int i, puntos[5], max; cout << "Tecle 5 puntajes: "; cin >> puntos[0]; max = puntos[0]; for(i=1; i<5; i++){ cin >> puntos[i]; if(puntos[i]>max) max = puntos[i]; }
cout <<"el puntaje mas alto es "<<max<< "n. Las diferencias respecto al mas alto son: n"; for(i=0; i<5; i++) cout << puntos[i]<<" con diferencia de "<< (max-puntos[i])<<endl; system("pause"); }
Inicialización de un arreglo Un arreglo puede iniciarse con una lista de valores entre llaves. Si el número de valores es menor que el tamaño del arreglo, los faltantes se inician a 0. #include <iostream> using namespace std; int main(){ int n[10]={32, 27, 64, 18, 95, 14, 90, 70}; cout <<"Elementot. Valor" << endl; for ( int i = 0; i < 10; i++ ) cout<<i<<“t”<<n[i]<<endl; system(“pause”); }
Otra inicialización Puede usarse una constante para definir el tamaño de un arreglo Variable constante int main(){ const int tamano. Arreglo = 10; int s[tamano. Arreglo]; for (int i=0; i<tamano. Arreglo; i++) s[ i ] = 2 + 2 * i; cout << "Elementot. Valor" << endl; for ( int j = 0; j < tamano. Arreglo; j++ ) cout << j << “t” << s[ j ] << endl; system(“pause”); }
Suma de un arreglo Suma los elementos de un arreglo int main() { const int tamano. Arreglo = 10; int a[tamano. Arreglo] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int total = 0; for ( int i = 0; i < tamano. Arreglo; i++ ) total += a[ i ]; cout <<"El total de los elementos del arreglo es "<< total << endl; system(“pause”); }
Promedio y desviación estándar El promedio y la desviación estándar de una serie de valores se puede calcular con las siguientes fórmulas. Por ejemplo: Dados los valores: 234679 El promedio es: 5. 16667 Y la desviación estándar es: 2. 63944 Para los valores: 555556 El promedio es: 5. 16667 Y la desviación estándar es: 0. 408248
#include <iostream> #include <cmath> using namespace std; main(){ const int MAX = 6; int a[MAX] = {2, 3, 4, 6, 7, 9}, i; float total = 0, prom, desv; for (i = 0; i<MAX; i++ ) total += a[i]; prom = total/MAX; total = 0; for (i = 0; i<MAX; i++ ) total += (a[i]-prom)*(a[i]-prom); desv = sqrt(total/(MAX-1)); cout <<"El promedio del arreglo es "<<prom<<endl; cout <<"La desviación estándar es : "<<desv<<endl; system("pause"); }
Histograma #include <iostream> #include <iomanip> using namespace std; int main(){ const int MAX = 10; int n[MAX] = {19, 3, 15, 7, 11, 9, 13, 5, 17, 1}, i, j; cout << "Elemento" << setw( 13 ) << "Valor" << setw( 17 ) << "Histograma" << endl; for (i = 0; i<MAX; i++ ) { cout <<setw(7)<<i<<setw( 13 )<<n[i]<<setw(9); //despliega una barra for(j = 0; j<n[ i ]; j++) cout << '*'; cout << endl; } system("pause"); }
Salida del programa Elemento Valor 0 19 1 3 2 15 3 7 4 11 5 9 6 13 7 5 8 17 9 1 Histograma ********** *********** *********** * Presione una tecla para continuar. . .
La criba de Eratóstenes es un método para encontrar números primos. Se tiene una lista de números de 1 hasta un máximo. Luego se tachan todos los múltiplos de 2, luego los de 3, los de 4, etc. Hasta llegar a los múltiplos del elemento que se encuentra a la mitad. Los elementos no marcados son números primos. Para números de 1 a 20 se tiene: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Primos: 1, 2, 3, 5, 7, 11, 13, 17, 19
#include <iostream> #include <cmath> using namespace std; main(){ int N = 100, i, j, k; int primo[N]; //inicia con todos primos for(i = 0; i<N; i++) primo[i] = 1; //tacha los multiplos de i for(i = 2; i<=N/2; i++) for(j = 2; j<=N/i; j++) if(i*j<N) primo[i*j] = 0; for(i = 0; i<N; i++) if(primo[i]) cout << " " << i; cin. get(); }
Paso de arreglos a funciones Para pasar un arreglo a una función debemos conocer su tamaño para poder saber cuantos elementos se van a procesar. Para esto declare la función con un parámetro extra pasar el número de elementos a la función Los arreglos pasan por referencia a las funciones, esto quiere decir que los elementos pueden ser modificados dentro de la función. Puede usarse la palabra const en la declaración de parámetros para prevenir modificaciones inesperadas.
Ejemplo #include <iostream> double promedio(double a[], int tamanio){ double suma = 0; for(int i=0; i<tamanio; i++) suma += a[i]; return suma/tamanio; } int main(){ double x[] = {3. 5, 6. 3, 4. 5, 7. 5, 5. 4}; cout << promedio(x, 5) << endl; getch(); return 0; }
Modificación de elementos mediante funciones En C los arreglos siempre se pasan por referencia de tal manera que siempre es posible modificar los elementos dentro de una función. Ejemplo, inicia un arreglo con valores aleatorios entre 0 y 99. void inicia(double a[], int tamanio){ for(int i=0; i<tamanio; i++) a[i] = rand()%100; }
Lectura de valores La siguiente función permite leer un arreglo de enteros de cualquier tamaño. void leer. Arreglo(int a[], int tamanio){ int i; cout <<“Teclee ”<<tamanio<<“ numeros. n”; for(i=0; i<tamanio; i++) cin >>a[i]; }
Escritura de valores La siguiente función permite desplegar un arreglo de enteros de cualquier tamaño. void escribe. Arreglo(int a[], int tamanio){ int i; for(i=0; i<tamanio; i++) cout <<a[i]; cout << endl; }
Ejemplo de lectura y escritura El siguiente programa usa las dos funciones anteriores: main(){ int m[10], n[5]; leer. Arreglo(m, 10); leer. Arreglo(n, 5); escribe. Arreglo(m, 10); escribe. Arreglo(n, 5); system("pause"); }
Ejemplo de diseño descendente Se desea un programa para procesar los datos de temperatura de cada día del mes. El programa leerá los valores de las temperaturas y calculará la temperatura promedio, la más alta y la más baja y la diferencia entre la más alta y la más baja. main(){ float temp[31]; int n. Dias; solicitar. Datos(temp, n. Dias); imprimir. Resultados(temp, n. Dias); system(“pause”); }
Función solicitar. Datos Esta función solicita el número de datos y los datos de las temperaturas. Note que total pasa por referencia. void solicitar. Datos(float t[], int &total){ int i; do{ cout <<"numero de dias? "; cin >>total; }while(total<1 or total>31); cout <<"Teclee "<<total<<" datos. n"; for(i=0; i<total; i++) cin >>t[i]; }
Función imprimir. Resultados Esta función procesa las temperaturas leídas. Calcula el promedio y los valores máximos y mínimos. void imprimir. Resultados(float t[], int total){ int i; float suma=0, prom, mayor, menor; //calcula promedio for(i=0; i<total; i++) suma += t[i]; prom = suma/total;
//determina la mayor y la menor temperatura mayor = t[0]; menor = t[0]; for(i=0; i<total; i++) if(t[i]>mayor) mayor = t[i]; else if(t[i]<menor) menor = t[i]; cout<<"La temparetura promedio es: "<<prom<<endl; cout<<"La temparetura mas alta es: "<<mayor<<endl; cout<<"La temparetura mas baja es: "<<menor<<endl; cout<<"La diferencia es: "<<mayor-menor<<endl; }
Ordenación La operación de ordenación es de las más comunes en computación. #include <iostream. h> #include <conio. h> void Burbuja(int a[], int tam){ for(int i = 0; i< tam - 1 ; i++) for(int j = i; j< tam; j++) if(a[i]>a[j]){ int temp = a[i]; a[i]=a[j]; a[j]=temp; } } int main(){ int b[20] = {1, 2, 3, 2, 4, 3, 5, 6, 3, 7, 8, 9, 4, 5, 3, 4, 5, 6}; Burbuja(b, 20); for(int i =0; i<20; i++) cout << b[i] << endl; getch(); return 0; }
Búsqueda Otra operación importante es la búsqueda de el valor de un elemento dentro de un arreglo. int Busqueda. Lineal(int a[], int b, int tam){ for(int i = 0; i< tam; i++) if(a[i]==b) return n; return -1; }
Arreglos de dos dimensiones Los arreglos de dos dimensiones se declaran de acuerdo al esquema tipo variable[renglones][columnas]; Ejemplo int a [5][4]; a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] a[3][0] a[3][1] a[3][2] a[3][3] a[4][0] a[4][1] a[4][2] a[4][3]
inicialización int a[5][4] = {{2, 3, 4, 2}, {2, 0, 6, 1}, {3, 5, 5, 0}, {2, 2, 1, 1}, {3, 2, 5, 6}}; 2 3 4 2 2 0 6 1 3 5 5 0 2 2 1 1 3 2 5 6
inicialización (cont. ) int a[5][4] = {{2, 3}, {1}, {3, 5, 5, 0}, {2}, {3}}; 2 3 0 0 1 0 0 0 3 5 5 0 2 0 0 0 3 0 0 0
ejemplo Debe especificarse void despliega. Arreglo( int a[][ 3 ] ){ for ( int i = 0; i < 2; i++ ) {// for para cada fila for ( int j = 0; j < 3; j++ )//despliega los valores de columnas cout << a[ i ][ j ] << ' '; cout << endl; // inicia una nueva línea de salida } // fin de la estructura for externa } // fin de la función despliega. Arreglo int main(){ int arreglo 1[ 2 ][ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 } }; int arreglo 2[ 2 ][ 3 ] = { 1, 2, 3, 4, 5 }; int arreglo 3[ 2 ][ 3 ] = { { 1, 2 }, { 4 } }; cout << "Los valores del arreglo 1 por fila son: " << endl; despliega. Arreglo( arreglo 1 ); cout << "Los valores del arreglo 2 por fila son: " << endl; despliega. Arreglo( arreglo 2 ); cout << "Los valores del arreglo 3 por fila son: " << endl; despliega. Arreglo( arreglo 3 ); return 0; // indica terminación exitosa } // fin de main
Operaciones con matrices Se puede utilizar la técnica vista anteriormente para matrices de tamaño fijo. Si las matrices que se van a manipular son de 3 x 3 la función para sumar podría ser void Suma(double a[][3], double b[][3], double c[][3]){ for(int i = 0; i< 3 ; i++) for(int j = 0; j< 3 ; j++) c[i][j] = a[i][j] + b[i][j]; }
Otras operaciones de matrices void Resta(double a[][3], double b[][3], double c[][3]){ for(int i = 0; i< 3 ; i++) for(int j = 0; j< 3 ; j++) c[i][j] = a[i][j] - b[i][j]; } void Multiplica(double a[][3], double b[][3], double c[][3]){ for(int i = 0; i< 3 ; i++) for(int j = 0; j< 3 ; j++){ c[i][j] = 0; for(int k = 0; k< 3 ; k++) c[i][j] += a[i][k]*b[k][j]; } }
Otras operaciones de matrices impresión de una matriz de 3 x 3 void print(double a[][3]){ for(int i = 0; i< 3 ; i++){ for(int j = 0; j< 3 ; j++) cout << a[i][j] << " "; cout << endl; }
Tarea #10 Escriba una función para obtener la traspuesta de una matriz de 3 x 3. Escriba una función que calcule la suma de todos los elementos de una matriz de 3 x 3 Escriba una función que calcule la traza de una matriz de 3 x 3 Calcule con esta tarea y lo anterior lo siguiente: a + b, a - b, a * b, traspuesta(a), traspuesta(b), traza(a), traza(b), sumatotal(a), sumatotal(b),
Matrices de cualquier tamaño Es conveniente manejar las matrices de tamaño arbitrario mediante un vector de una sola dimensión. La matriz que se pasa como parámetro se pasa como un apuntador. Las funciones para manipular matrices se definen para un tamaño máximo de elementos.
Ejemplo suma Tamaño real de las matrices Debe especificarse máximo tamaño void suma. Mat(int nr. Row, int nr. Col, int max. Col, float *mat 1, float *mat 2, float *mat 3) { int i, j; for( i=0; i<nr. Row; i++ ) for( j=0; j<nr. Col; j++ ) mat 3[i*max. Col + j] = mat 1[i*max. Col + j] + mat 2[i*max. Col + j]; // o: mat 3[i*max. Col + j] = *(mat 1 + i*max. Col + j) // + *(mat 2 + i*max. Col + j) }
producto void prod. Mat(int nr. Row, int nr. Col, int max. Col, float *mat 1, float *mat 2, float *mat 3) { int i, j, k; for( i=0; i<nr. Row; i++ ) for( j=0; j<nr. Col; j++ ){ mat 3[i*max. Col + j] = 0; for( k=0; k<nr. Col; k++ ) mat 3[i*max. Col + j] += mat 1[i*max. Col + k] * mat 2[k*max. Col + j]; } }
Impresión void print. Mat(int nr. Row, int nr. Col, int max. Col, float *mat) { int i, j; for( i=0; i<nr. Row; i++ ){ for( j=0; j<nr. Col; j++ ) cout << mat[i*max. Col + j] << " "; cout << endl; }
Ejemplo de programa principal int main(void) { int row=4, col=4; float add, max. Row; float a[MAXROW][MAXCOL] = {{1, 2, 3, 4}, {3, 2, 1, 1}, {4, 3, 7, 6}, {4, 5, 5, 6}}; float b[MAXROW][MAXCOL] = {{4, 5, 7, 1}, {2, 4, 8, 9}, {3, 3, 0, 0}, {2, 1, 1, 1}}; float c[MAXROW][MAXCOL]; print. Mat(row, col, MAXCOL, (float *) a); print. Mat(row, col, MAXCOL, (float *) b); suma. Mat(row, col, MAXCOL, (float *) a, (float *) b, (float *) c); print. Mat(row, col, MAXCOL, (float *) c); getch(); return 0; }
Manejo de la consola Las siguientes funciones permiten llevar a cabo algunaas operaciones de consola. Para utilizarlas debe incluir la biblioteca <windows. h>. gotoxy(int x, int y) – posiciona el cursor en la coordenada especificada (1<=x<=80, 1<=y<=24). textcolor(int c) – pone el color del texto (0<=c<=15). textbkcolor(int c) – pone el color del fondo del texto (0<=c<=15).
void gotoxy(int x, int y) { COORD c; c. X = x - 1; c. Y = y - 1; Set. Console. Cursor. Position (Get. Std. Handle(STD_OUTPUT_HANDLE), c); } void textcolor(int c){ c = c & 0 x 0 f; Set. Console. Text. Attribute (Get. Std. Handle( STD_OUTPUT_HANDLE), c); } void textbkcolor(int c){ c = c << 4; Set. Console. Text. Attribute (Get. Std. Handle(STD_OUTPUT_HANDLE), c); }
Ciclo de espera La siguiente función utiliza el reloj de tiempo real para suspender el programa durante un tiempo determinado. Utiliza la biblioteca <time. h>: void espera(){ time_t comienzo, final; comienzo = time( NULL ); do{ final = time( NULL ); }while(difftime(final, comienzo)<1); }
El juego de la vida Este consiste en simular una población bidimensional de células. Las células pueden estar en uno de dos estados posibles, vivas (1) o muertas (0). Las células interactúan con sus ocho vecinos, dos a cada lado, uno arriba, otro abajo y cuatro en dirección diagonal. En cualquier momento pueden ocurrir las siguientes transiciones:
El juego de la vida 1. Una célula que tenga menos de dos vecinos muere por causa de la baja población. 2. Una célula que tenga más de tres vecinos muere por causa de la alta población. 3. Una célula que tenga dos o tres vecinos sobrevive a la siguiente generación. 4. Una célula muerta que tenga exactamente tres vecinos vivos, vuelve a la vida
Ejemplo de transición
El juego de la vida Representaremos el mundo donde viven las células mediante un arreglo de dos dimensiones llamado mundo. Usaremos un arreglo de las mismas dimensiones para hacer los cálculos en cada paso sin alterar el estado inicial. Se utilizan dos vectores, dx y dy, para generar los índices de los vecinos de cada célula. Inicialmente el mundo tiene valores aleatorios de 0 y 1 o alguna configuración arbitraria. A cada paso se copia el mundo en el arreglo temporal, y después se aplican las reglas de sobre vivencia al arreglo temporal elemento por elemento y se actualiza el arreglo mundo.
Algotirmo Algoritmo Juego de la Vida 1. Establecer configuración inicial 2. REPETIR 3. Dibujar el mundo 4. Copiar el mundo a un arreglo temporal 5. Aplicar las reglas de evolución 6. Esperar 7. HASTA terminar
Dibujar el mundo La forma más simple de dibujar el mundo es usar la pantalla de texto. Usaremos un punto para indicar una célula muerta y un 0 para una célula viva. void dibuja. Mundo(int mundo[][MAXCOL]){ int i, j; for(i=0; i<MAXREN; i++) for(j=0; j<MAXCOL; j++){ gotoxy(j+1, i+1); if(mundo[i][j]) cout <<"0"; else cout <<". "; } }
Copiar mundo void copiar. Mundo(int mundo[][MAXCOL], int temp[][MAXCOL]){ int i, j; for(i=0; i<MAXREN; i++) for(j=0; j<MAXCOL; j++) temp[i][j] = mundo[i][j]; }
Aplicar reglas void ejecuta. Paso(int mundo[][MAXCOL], int temp[][MAXCOL]){ int i, j, k, x, y, suma; int dx[8]={-1, 0, 1, 1, 1, 0, -1}; int dy[8]={-1, -1, 0, 1, 1, 1, 0}; for(i=0; i<MAXREN; i++) for(j=0; j<MAXCOL; j++){ suma = 0; for(k=0; k<8; k++){ x = i+dx[k]; if(x<0) x=MAXREN-1; if(mundo[i][j]){ if(x==MAXREN) x=0; if(suma<2||suma>3) y = j+dy[k]; mundo[i][j]=0; if(y<0) y=MAXCOL-1; }else if(y==MAXCOL) y=0; mundo[i][j]=suma==3; suma += temp[x][y]; } } }
Programa principal #include <iostream> #include <time. h> #include <windows. h> #define MAXREN 20 #define MAXCOL 60 using namespace std; main(){ int mundo[MAXREN][MAXCOL], temp[MAXREN][MAXCOL]; int i, j; srand(time(0)); for(i=0; i<MAXREN; i++) for(j=0; j<MAXCOL; j++) mundo[i][j]=rand()%2; do{ dibuja. Mundo(mundo); copiar. Mundo(mundo, temp); ejecuta. Paso(mundo, temp); espera(1); }while(1); }
Configuraciones interesantes El patrón "Diehard" desaparece después de 130 turnos, mientras que "Acorn" tarda 5206 turnos en estabilizarse en forma de muchos osciladores, y en ese tiempo genera 13 planeadores.
La primera pistola de planeadores que se ha descubierto sigue siendo la más pequeña que se conoce:
Se han hallado posteriormente patrones más simples que también crecen indefinidamente. Los tres patrones siguientes crecen indefinidamente. Los dos primeros generan un motor interruptor que deja bloques, mientras que el tercero genera dos. El primero tiene una población mínima de 10 células vivas, el segundo cabe en un cuadrado 5 × 5 y el tercero sólo tiene un cuadrado de altura:
- Slides: 53