Tema III. Diseño de programas que con estructuras de...

Post on 03-Apr-2020

5 views 0 download

Transcript of Tema III. Diseño de programas que con estructuras de...

Programación 1

Tema III. Diseño de programas que trabajan con estructuras de datos

Lección 9. Estructuración indexada de datos

1

Objetivos de la lección :• Conocer las características de las estructuras de

datos indexadas (vectores, tablas o arrays)• Aprender a trabajar con vectores (tablas) de datos

unidimensionales:– Aplicación a la resolución de problemas que trabajan con

vectores (tablas) de datos de diferente naturaleza– Aplicación a la programación de cálculos estadísticos de

datos numéricos (media, desviación típica y moda)

• Aprender a trabajar con vectores (tablas) de datosmultidimensionales:– Aplicación a la resolución de problemas con matrices

numéricas2

1.  Estructuras de datos indexadas• Son estructuras que almacenan una colección de datos del

mismo tipo accesibles mediante uno o más índices– En C++ cada índice toma valores a partir de 0: { 0, 1, 2, ...}

3

v0 d11 d2… ...

i   di… ...

N‐2 dN‐1N‐1 dN

M

0 1 ... j ... NC‐2 NC‐1

0 d1,1 d1,2 ... ... ... ... ...

1 d2,1 d2,2 ... ... ... ... ...

... ... ... ... ... ... ... ...

i ... ... ... d i,j ... ... ...

... ... ... ... ... ... ... ...

NF‐2 ... ... ... ... ... ... ...

NF‐1 ... ... ... ... ... ... dNF,NC

Declaración y creación de tablas (I)– Deben ser creadas con un número de datos determinado– Se reserva memoria para alojar, de forma contigua, sus datos– En principio, el valor de los datos estructurados en una tabla está

indefinido

// Dimensiones de las tablas que se definen a continuaciónconst int N = … , // número de elementos del vector <v>

NF = … , // número de filas de la matriz <M>NC = … ; // número de columnas de la matriz <M>

int v[N]; // Creación de una tabla undimensional (vector)// con N elementos de tipo int

double M[NF][NC]; // Creación de una tabla bidimensional// (matriz) con NF x NC elementos// de tipo double

4

Declaración y creación de tablas (II)– Es posible definir los valores iniciales de una tabla en la propia

instrucción de creación. En tal caso no es necesario especificar elnúmero de valores posibles del primer índice.

char letrasRomanas[] = { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };int valoresLetrasRomanas[] = { 1, 5, 10, 50, 100, 500, 1000 };int matrizIdentidad[][3] = {

{ 1, 0, 0 },{ 0, 1, 0 },{ 0, 0, 1 }

};

5

2. Trabajo con tablasSelección de un elemento de un tabla (vector) mediante el operador de selección []:  nombreTabla[expresiónIndice]

int v[DIM];for (int i = 0; i < DIM; ++i) {

v[i] = i + 1;}…int suma = 0;for (int i = 0; i < DIM; ++i) {

suma = suma + v[i];}…for (int i = 1; i < DIM; ++i) {

v[i] = v[i‐1] + v[i];}

6

Funciones que trabajan con tablas (vectores):– Las operaciones con tablas conviene encapsularlas en una función en

la que esas tablas consten en la lista de parámetros– Por razones de eficiencia en C++ las tablas parámetro de una función

se transmiten por referencia (no se transmite su contenido sino sudirección en memoria). Para nombrar una tabla en la lista deparámetros no se utiliza el operador &, sino el nombre de la tablaseguido de un par de corchetes

– Conviene determinar el número de datos o, en su caso, los índicesrelevantes de la tabla mediante parámetros adicionales

int sumar (int v[], int n) {int suma = 0;for (int i = 0; i < n; ++i) {

suma = suma + v[i];}return suma;

}6

Funciones que trabajan con tablas (vectores):– Se puede garantizar que el contenido de una tabla que sea parámetro

de una función no pueda ser modificado por el propio código de lafunción. Para ello basta comenzar la declaración del parámetro con lapalabra reservada const.

int sumar (const int v[], int n) {int suma = 0;for (int i = 0; i < n; ++i) {

suma = suma + v[i];}return suma;

}

6

3. Trabajo con vectores (tablas unidimensionales)

Diseñar la siguiente función:

/** Pre: n < 100* Post: Devuelve <true> si y sólo si <n> es un número primo*/bool esPrimo (int n);

9

/** Pre: n < 100* Post: Devuelve <true> si y sólo si <n> es un número primo*/bool esPrimo (int n) {

const int NUM_PRIMOS = 25;const int TABLA_PRIMOS[] = { 2,  3,  5,  7, 11, 13, 17, 19, 23, 29,

31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };if (n < 2) { return false; }else {

bool confirmadoQueEsPrimo = false;int i = 0;while (!confirmadoQueEsPrimo && i < NUM_PRIMOS) {

if (TABLA_PRIMOS[i] == n) { confirmadoQueEsPrimo = true; }else { i = i + 1; }

}return confirmadoQueEsPrimo;

}}

10

Trabajo con una tabla (vector) de caracteres

11

TABLA DE LETRAS DE LOS NIF

dni % 23 letra dni % 23 letra dni % 23 letra

0 T 8 P 16 Q

1 R 9 D 17 V

2 W 10 X 18 H

3 A 11 B 19 L

4 G 12 N 20 C

5 M 13 J 21 K

6 Y 14 Z 22 E

7 F 15 S

Validación de un NIF

/**  Pre: ‐‐‐*  Post: Devuelve <true> si y sólo si el par (<dni>,<letra>) definen *        un número de identificación fiscal (NIF) válido*/bool validar (int dni, char letra) {

… ¿? …

}

12

/**  Pre: ‐‐‐*  Post: Devuelve <true> si y sólo si el par (<dni>,<letra>) definen un*        número de identificación fiscal (NIF) válido*/bool validar (int dni, char letra) {

const int NUM_LETRAS = 23;const char TABLA_NIF[] = 

{ 'T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E' };

return TABLA_NIF[dni % NUM_LETRAS] == letra;}

13

Cálculo de la letra de un NIF 

/** Pre: ‐‐‐* Post: Devuelve la letra del número de identificación fiscal que *       corresponde a un número de documento nacional de identidad*       igual a <dni>*/char letra (int dni) {

… ¿? …

}

14

/** Pre: ‐‐‐* Post: Devuelve la letra del número de identificación fiscal que *       corresponde a un número de documento nacional de identidad*       igual a <dni>*/char letra (int dni) {

const int NUM_LETRAS = 23;const char TABLA_NIF[] = 

{ 'T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E' };

return TABLA_NIF[dni % NUM_LETRAS];}

15

Cálculo de la media aritmética de una distribución de datos

/**  Pre: n > 0*  Post: Devuelve la media aritmética de los elementos de*        v[0..n‐1]*/

double media (const double v[], int n) {

… ¿? …

}

16

/**  Pre: n > 0*  Post: Devuelve la media aritmética de los elementos de*        v[0..n‐1]*/

double media (const double v[], int n) {// En <suma> no se ha acumulado aún ningún elemento de <v>double suma = 0.0;for (int i = 0; i < n; ++i) {

// Acumula v[i], elemento i‐ésimo del vector <v>suma = suma + v[i];

}// Devuelve el valor promedio de los <n> elementos sumadosreturn suma / n;

}

17

Cálculo de la desviación típica de una distribución de datos

/**  Pre: n > 1*  Post: Devuelve la desviación típica de los elementos *        de v[0..n‐1]*/

double desviacion (const double v[], int n) {

… ¿? …

}

18

/**  Pre: n > 1*  Post: Devuelve la desviación típica de los elementos  *        de v[0..n‐1]*/

double desviacion (const double v[], int n) {double mediaAritmetica = media(v,n),

suma = 0.0;for (int i = 0; i < n; ++i) {

suma = suma + pow(v[i] ‐ mediaAritmetica, 2.0);}return sqrt(suma / (n ‐ 1));

}

19

Cálculo de la moda de una distribución de datos

/**  Pre: n > 0*  Post: Devuelve la moda de los elementos de v[0..n‐1]*/int moda (const int v[], int n) {

… ¿? …

}

20

/**  Pre: n > 0*  Post: Devuelve la moda de los elementos de v[0..n‐1]*/int moda (const int v[], int n) {

int iModa = 0;          // Indice del primer elemento a considerarint repeticionesModa = 1;for (int j = iModa + 1; j < n; ++j) {

if (v[iModa] == v[j]) { ++repeticionesModa; }}// Analiza las repeticiones de los restantes elementos de v[1,n‐1]// y retiene en iModa el índice del más repetidofor (int i = 1; i < n; ++i) {

int repeticionesNuevo = 1;for (int j = i + 1; j < n; ++j) {

if (v[i] == v[j]) { ++repeticionesNuevo; }} if (repeticionesModa < repeticionesNuevo) { iModa = i; }   

}return v[iModa];       // Devuelve el elemento más repetido

} 21

4. Trabajo con matrices (tablas multidimensionales)

const int DIM = 12;      // Dimensión de las matrices del ejemplo

/** Pre: DIM > 0 y MIN <= MAX* Post: Asigna a los elementos de la matriz cuadrada <m> valores *       pseudo‐aleatorios comprendidos entre MIN y MAX*/void definirValores (int m[DIM][DIM]) {

const int MIN = ‐10, MAX = 10;srand (time(NULL));    // inicia el generador en función del tiempofor (int i = 0; i < DIM; ++i) {

for (int j = 0; j < DIM; ++j) {m[i][j] = MIN + rand() % (MAX – MIN + 1);

}}

}22

/** Pre: DIM > 0 y <m> es una matriz cuadrada de dimensión DIM x DIM* Post: Presenta por pantalla los elementos de la matriz <m> a razón*       de una fila por línea, utilizando un número de caracteres*       igual a ANCHO para presentar cada elemento*/void mostrarValores (const int m[DIM][DIM]) {

// Anchura de cada columnaconst int ANCHO = 6;// Presentación por pantalla de los elementos de la matriz <m>for (int i = 0; i < DIM; ++i) {

// Presenta en una línea la fila i‐ésima de <m>for (int j = 0; j < DIM; ++j) {

// Presenta el elemento j‐ésimo de la fila i‐ésima de <m>cout << setw(ANCHO) << m[i][j];

}cout << endl;

}cout << endl;

}23

/** Pre: DIM > 0 y <m> es una matriz cuadrada de dimensión DIM x DIM* Post: La matriz <m> es igual a la transpuesta de su valor inicial*/void transponer (int m[][DIM]) {

// Recorre los elementos de la matriz <m> situados por encima// de su diagonal principal y los permuta con sus elementos // simétricos, respecto de dicha diagonalfor (int i = 0; i < DIM ‐ 1; ++i) {

for (int j = i + 1; j < DIM; ++j) {// Permuta los elementos m[i][j] y m[j][i]int aux = m[i][j];m[i][j] = m[j][i];  m[j][i] = aux;

}}

}

24

25