C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4....

103
ÍNDICE GENERAL 1 Índice general 4.1. Vectores ......................... 2 4.1.1. Motivación .................... 2 4.1.2. Declaración y Representación en Memoria . 5 4.1.3. Operaciones con Vectores .......... 6 4.1.4. Modularización y Vectores .......... 16 4.1.5. Algoritmos de Búsqueda ........... 30 4.1.6. Construcción de vectores en una función . 39 4.1.7. Trabajando con vectores locales ....... 44 4.1.8. Algoritmos de Ordenación .......... 48 4.1.9. Cadenas de caracteres (cstring) ....... 73 4.2. Matrices ......................... 83 4.2.1. Introducción ................... 83 4.2.2. Operaciones con matrices .......... 86 4.2.3. Gestión de componentes útiles con matrices 88 4.2.4. Matrices de varias dimensiones ....... 92 4.2.5. Modularización con Matrices ......... 93 4.2.6. Gestión de filas de una matriz como vectores 99

Transcript of C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4....

Page 1: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

ÍNDICE GENERAL 1

Índice general4.1. Vectores . . . . . . . . . . . . . . . . . . . . . . . . . 2

4.1.1. Motivación . . . . . . . . . . . . . . . . . . . . 2

4.1.2. Declaración y Representación en Memoria . 5

4.1.3. Operaciones con Vectores . . . . . . . . . . 6

4.1.4. Modularización y Vectores . . . . . . . . . . 16

4.1.5. Algoritmos de Búsqueda . . . . . . . . . . . 30

4.1.6. Construcción de vectores en una función . 39

4.1.7. Trabajando con vectores locales . . . . . . . 44

4.1.8. Algoritmos de Ordenación . . . . . . . . . . 48

4.1.9. Cadenas de caracteres (cstring) . . . . . . . 73

4.2. Matrices . . . . . . . . . . . . . . . . . . . . . . . . . 83

4.2.1. Introducción . . . . . . . . . . . . . . . . . . . 83

4.2.2. Operaciones con matrices . . . . . . . . . . 86

4.2.3. Gestión de componentes útiles con matrices 88

4.2.4. Matrices de varias dimensiones . . . . . . . 92

4.2.5. Modularización con Matrices . . . . . . . . . 93

4.2.6. Gestión de filas de una matriz como vectores 99

Page 2: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 2

TEMA 4. VECTORES Y MATRICES

4.1. VECTORES

4.1.1. MOTIVACIÓN

En casi todos los problemas, es necesario mantener una rela-ción entre variables diferentes o almacenar y referenciar varia-bles como un grupo. Para ello, los lenguajes ofrecen tipos máscomplejos que los vistos hasta ahora.

Un tipo de dato compuesto es una composición de tipos dedatos simples (o incluso compuestos) caracterizado por la or-ganización de sus datos y por las operaciones que se definensobre él.

Un vector es un tipo de dato, compuesto de un número fijo decomponentes del mismo tipo y donde cada una de ellas es di-rectamente accesible mediante un índice.

Page 3: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 3

Ejemplo:

#include <iostream>

using namespace std;

int main(){

int cuantos;

double nota1, nota2, nota3, media;

cout << "Introduce nota 1: ";

cin >> nota1;

cout << "Introduce nota 2: ";

cin >> nota2;

cout << "Introduce nota 3: ";

cin >> nota3;

media = (nota1+nota2+nota3)/3.0;

cuantos=0;

if (nota1 > media)

cuantos++;

if (nota2 > media)

cuantos++;

if (nota3 > media)

cuantos++;

cout << "Media Aritmetica = " << media << endl;

cout << cuantos << " alumnos han superado la media\n";

return 0;

}

Page 4: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 4

Problema: ¿Qué sucede si queremos almacenar las notas de50 alumnos?

Número de variables imposible de sostener y recordar

Solución: Introducir un tipo de dato nuevo que permita repre-sentar dichas variables en una única estructura de datos, reco-nocible bajo un nombre único.

notas[0] notas[1] notas[2]

notas= 2.4 4.9 6.7

Page 5: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 5

4.1.2. DECLARACIÓN Y REPRESENTACIÓN EN MEMO-RIA

<tipo> <identificador>[<N.Componentes>];

<tipo> indica el tipo de dato común a todas las compo-nentes del vector.

<N.Componentes> determina el número de componentes delvector. El número de componentes debe conocerse a prioriy no es posible alterarlo durante la ejecución del programa.Pueden usarse literales ó constantes enteras (char, int, ...),pero nunca una variable

Las posiciones ocupadas por el vector están contiguas enmemoria.

double notas[3];

notas = ? ? ?

Consejo: Fomentad el uso de constantes para especificarel tamaño de los vectores.

int main(){

const int TOTAL_ALUMNOS = 100;

double notas[TOTAL_ALUMNOS];

}

Page 6: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 6

Otros ejemplos:

int main(){

const int NUM_REACTORES=20;

int longitud=50;

int TemperaturasReactores[NUM_REACTORES]; // Correcto.

bool casados[40]; // Correcto.

char DNI[8]; // Correcto.

bool vector[longitud]; // Error en compilación.

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

}

4.1.3. OPERACIONES CON VECTORES

4.1.3.1. ACCESO

Dada la declaración:<tipo> <identificador>[<N.Componentes>];

Cada componente se accede de la forma:

<Identificador de vector> [ <índice> ]

0 ≤ índice < N.Componentes

El índice de la primera componente del vector es 0.El índice de la última componente es <N.Componentes>-1.

Page 7: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 7

double notas[3];

notas

notas[0] notas[1] notas[2]

? ? ?

? ? ?

notas[9] y notas[’3’] no son componentes correctas.

Cada componente es una variable más del programa, deltipo indicado en la declaración del vector. Por ejemplo, sideclaramos

double vector[3];

entonces vector[2] y vector[0] son variables de tipo double

Por lo tanto, con dichas componentes podremos realizartodas las operaciones disponibles (asignación, lectura concin, pasarla como parámetros actuales, etc)

Page 8: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 8

4.1.3.2. ASIGNACIÓN

<Ident. vector> [ < índice> ] = <Expresión>;

<Expresión> ha de ser del mismo tipo que el definido enla declaración del vector (o al menos compatible).

No se permiten asignaciones globales sobre todos los ele-mentos del vector. Las asignaciones se deben realizar com-ponente a componente.

int main(){

double notas[3];

notas[0] = 5;

notas

notas[0] notas[1] notas[2]

? ? ?

5 ? ?

Page 9: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 9

4.1.3.3. LECTURA Y ESCRITURA

La lectura y escritura se realiza componente a componente.

Para leer con cin o escribir con cout todas las componentesutilizaremos un bucle, como por ejemplo:

#include <iostream>

using namespace std;

int main(){

const int NUM_NOTAS = 10;

double notas[NUM_NOTAS], media;

for (int i=0; i<NUM_NOTAS; i++){

cout << "Introducir nota del alumno " << i << ": ";

cin >> notas[i];

}

media = 0;

for (int i=0; i<NUM_NOTAS; i++){

media = media + notas[i];

}

media = media / NUM_NOTAS;

cout << "\nMedia = " << media;

}

Page 10: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 10

int main(){

const int DIM_VECTOR = 10;

double vector[DIM_VECTOR], dato;

dato = vector[0]; // Error logico ¿vector[0]?

for (int i=0 ; i<DIM_VECTOR ; i++)

vector[i] = 2*i; // <- double = int

dato = vector[0]; // Correcto

vector[15]=7; // Posible error grave en ejecucion!

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

return 0;

}

Muy importante: El compilador no comprueba el acceso a lascomponentes, por lo que cualquier modificación de una com-ponente inexistente tiene consecuencias imprevisibles.

Page 11: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 11

4.1.3.4. INICIALIZACIÓN

C++ permite inicializar una variable de tipo vector, en la decla-ración.

int vector[3]={4,5,6};

inicializa vector[0]=4 vector[1]=5 vector[2]=6

int vector[7]={3,5};

inicializa vector[0]=3 vector[1]=5 y el resto se inicializana cero.

int vector[7]={0};

inicializa todas las componentes a cero.

int vector[]={1,3,9};

automáticamente el compilador asume int vector[3]

4.1.3.5. TRABAJANDO CON EL VECTOR

No es necesario utilizar todas las componentes del vector. Loshuecos suelen dejarse en la zona de índices altos.

Por eso, el programador debe usar una variable entera, utilque indique el número de componentes usadas. Como conven-ción, usaremos identificadores del tipo utilNombreDelVector outil_nombreDelVector

Page 12: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 12

#include <iostream>

using namespace std;

int main(){

const int DIM_NOTAS = 100;

int util_notas;

double notas[DIM_NOTAS], media;

do{

cout << "Introduzca el n\’umero de alumnos (entre 1 y "

<< DIM_NOTAS << "): ";

cin >> util_notas;

}while (util_notas<1 || util_notas>DIM_NOTAS);

for (int i=0; i<util_notas; i++){

cout << "nota[" << i << "] --> ";

cin >> notas[i];

}

media=0;

for (int i=0; i<util_notas; i++){

media=media+notas[i];

}

cout << "\nMedia: " << media/util_notas << endl;

return 0;

}

Page 13: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 13

Ejemplo: Buscar un elemento en un vector.

Recorre las componentes vector[i] del vector

mientras no se terminen Y

mientras no se encuentre el elemento

Si vector[i] == elemento,

recuerda la posición y sal del bucle

si no

i++

#include <iostream>

using namespace std;

int main(){

const int DIM_VECTOR = 100;

double vector[DIM_VECTOR], buscado;

int i, util_vector;

bool encontrado;

util_vector=50;

for (i=0 ; i<util_vector ; i++)

vector[i] = i*i;

cout << "\n\nIntroduzca valor a buscar";

cin >> buscado;

Page 14: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 14

encontrado=false;

i=0;

while ((i<util_vector) && !encontrado)

if (vector[i] == buscado)

encontrado=true;

else

i++;

if (encontrado)

cout << "\nEncontrado en la posición "<< i;

else

cout << "\nNo encontrado";

}

encontrado=false;

for (i=0; i<util_vector && !encontrado ; i++)

if (vector[i] == buscado)

encontrado=true;

if (encontrado)

cout << "\nEncontrado en la posición " << i-1 ; // <-

else

cout << "\nNo encontrado" << endl;

}

Page 15: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 15

encontrado=false;

for (i=0; i<util_vector && !encontrado ; i++)

if (vector[i] == buscado){

posicion = i;

encontrado = true;

}

if (encontrado)

cout << "\nEncontrado en la posición " << posicion;

else

cout << "\nNo encontrado" << endl;

}

Ejercicio. Ver si un vector de caracteres es un palíndromo, esdecir, que se lee igual de izquierda a derecha que de derechaa izquierda. Por ejemplo, (’A’,’B’,’B’,’A’) sería un palíndro-mo.

Page 16: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 16

4.1.4. MODULARIZACIÓN Y VECTORES

4.1.4.1. PASANDO INDIVIDUALMENTE UNA COMPONENTE COMO

PARÁMETRO

Las componentes son variables cualesquiera por lo que laspodemos pasar como parámetro a cualquier función.

Ejemplo. De un vector de char, imprimid la mayúscula corres-pondiente a la primera componente.

char palabra[10];

palabra[0]=’h’;

palabra[1]=’o’;

palabra[2]=’l’;

palabra[3]=’a’;

cout << toupper(palabra[0]);

Si queremos, podemos modificar la componente:

char palabra[10];

palabra[0]=’h’;

palabra[1]=’o’;

palabra[2]=’l’;

palabra[3]=’a’;

palabra[0] = toupper(palabra[0]);

Page 17: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 17

Obviamente también funciona el paso por referencia.

Ejemplo. De un vector de int, incrementad en 1 el valor de to-das las componentes.

void Incrementa(int &dato){

dato = dato+1;

}

int main(){

int vector[10], int util_vector;

// Asignación de valores a las componentes

for(int i=0; i<util_vector; i++)

Incrementa(vector[i]);

}

Page 18: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 18

4.1.4.2. PASANDO TODAS LAS COMPONENTES COMO PARÁME-TRO

¿Podemos pasar de golpe todas las componentes a una fun-ción?

No puede pasarse una copia de todo el vector (como unpaso por valor)

Pero sí se puede indicar a la función dónde empieza el vec-tor (parámetro actual), para que la función acceda a suscomponentes.

Para indicar la dirección dónde empieza el vector, se pone[] en el parámetro formal.

... (tipoBase vector[], ...)

En la llamada, se pasa como parámetro actual el identifica-dor de un vector con el mismo tipo base que el correspon-diente parámetro formal (sin poner los corchetes [])

Page 19: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 19

#include <iostream>

using namespace std;

void ImprimeVector(double v[]){ // <- Con corchetes

for (int i=0; i<4; i++)

cout << v[i] << endl;

}

int main(){

double vector[4]={1,5,6,9};

ImprimeVector(vector); // <- Sin corchetes

}

Entorno de main

vector

Entorno de ImprimeVector

v

a a

1 5 6 9

Page 20: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 20

IMPORTANTE: la función podrá modificar las componentes delvector pasado como parámetro actual

#include <iostream>

using namespace std;

void Pon_a_cero(double v[]){ // <- NO SE PONE &

for (int i=0; i<4; i++)

v[i] = 0;

}

int main(){

double vector[4]={1,5,6,9};

Pon_a_cero(vector);

}

Entorno de main

1

vector

Entorno de Pon_a_cero

v

5 6 9

a a

Page 21: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 21

Las funciones ImprimeVector y Pon_a_cero sólo sirven para unvector de 4 componentes. Normalmente, pasaremos tambiéncomo parámetro a la función, el número de componentes utili-zadas (pero no la dimensión)

#include <iostream>

using namespace std;

void ImprimeVector (double v[], int util_v){

for (int i=0; i<util_v; i++)

cout << v[i] << endl;

}

int main(){

const int DIM_VECTOR = 5;

double vector[DIM_VECTOR]={4,2,7};

int util_vector=3;

ImprimeVector(vector, util_vector);

}

Entorno de main

3

4

vector

util_vector

Entorno de ImprimeVector

3 util_v

v

2 7 ? ?

a a

Page 22: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 22

Ejercicio. Calculad la mayor componente de un vector de double.

Page 23: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 23

Ejemplo. Cread un void llamado LecturaVectorDouble para leerdesde teclado los valores de un vector.

Primero, leyendo las componentes útiles dentro del void.

void LecturaVectorDouble (double v[], int &util_v){ // <- &

cout << "Introduzca número de componentes: ";

cin >> util_v;

cout << "\nIntroduzca valores reales:\n";

for (int i=0 ; i<util_v ; i++){

cout << "Posición " << i << ": ";

cin >> v[i];

}

}

int main(){

const int DIM_VECTOR = 5;

double vector[DIM_VECTOR]={4,2,7};

int util_vector;

LecturaVectorDouble(vector, util_vector);

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

}

Page 24: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 24

Segundo, leyendo dicho valor antes de llamar al void

void LecturaVectorDouble (double v[], int util_v){

cout << "\nIntroduzca valores reales:\n";

for (int i=0 ; i<util_v ; i++){

cout << "Posición " << i << ": ";

cin >> v[i];

}

}

int main(){

const int DIM_VECTOR = 5;

double vector[DIM_VECTOR]={4,2,7};

int util_vector;

cout << "Introduzca n\’umero de componentes: ";

cin >> util_vector;

LecturaVectorDouble(vector, util_vector);

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

}

¿Cual es preferible?

Page 25: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 25

En general, en una función cualquiera<tipo> funcion (TipoBase v[], ....)

indicamos al compilador que la función va a recibir por refe-rencia unas posiciones contiguas en memoria (las del vectorparámetro actual): cada una es de tipo de dato TipoBase. Deesta forma, cuando dentro del módulo accedamos a v[2], porejemplo, el compilador dará dos saltos tan grandes como digael TipoBase a partir de la primera posición del parámetro actual.

Entorno de main

3

4

vector

util_vector

Entorno de ImprimeVector

3 util_v

v

2 7 ? ?

a a

v [2]

Page 26: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 26

Al tener acceso desde la función a las componentes del vec-tor pasado como parámetro actual, se pueden producir efectoscolaterales indeseados.

#include <iostream>

using namespace std;

void Imprime_doble_de_vector (double v[], int util_v){

int i;

for (i=0; i<util_v; i++)

v[i]=2*v[i];

for (i=0; i<util_v; i++)

cout << v[i] << endl;

}

int main(){

const int DIM_VECTOR = 5;

double vector[DIM_VECTOR]={4,2,7};

int util_vector=3;

Imprime_doble_de_vector(vector, util_vector); // -> 8, 4, 14

for (i=0; i<util_v; i++)

cout << vector[i] << endl; // -> 8, 4, 14 !!!!

}

Page 27: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 27

Si se quiere pasar un vector a una función y que ésta no puedamodificarlo es necesario utilizar el calificador const.

#include <iostream>

using namespace std;

void Imprime_doble_de_vector (const double v[], int util_v){

int i;

for (i=0; i<util_v; i++)

v[i]=2*v[i]; // Error en compilación :-)

for (i=0; i<util_v; i++)

cout << v[i] << endl;

}

Representación en memoria: exactamente la misma.

Page 28: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 28

El parámetro actual y el formal han de ser del mismo tipo dedato: Con vectores, esto significa que han de tener el mismotipo de dato base (aunque tengan distintas dimensiones)

void ImprimeVector (const double v[], int util_v){

for (int i=0; i<util_v; i++)

cout << v[i] << endl;

}

int main(){

const int DIM_VECTOR_GRANDE = 10;

const int DIM_VECTOR_PEQUE = 5;

double vector_grande[DIM_VECTOR_GRANDE];

double vector_peque[DIM_VECTOR_PEQUE];

<Asignación de valores a los vectores>

// Todas estas llamadas son correctas:

ImprimeVector (vector_grande , 4);

ImprimeVector (vector_grande , 5);

ImprimeVector (vector_peque , 4);

ImprimeVector (vector_peque , 5);

ImprimeVector (vector_peque , 9);// Imprime basura a partir

// de la sexta posicion

}

Page 29: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 29

Sin embargo no podemos pasar como parámetros actuales,vectores de tipo de dato base compatible con el formal.

void ImprimeVector (const double v[], int util_v){

for (int i=0; i<util_v; i++)

cout << v[i] << endl;

}

int main(){

const int DIM_VECTOR_INT = 10;

const int DIM_VECTOR_DOUBLE = 10;

int vector_int[DIM_VECTOR_INT];

double vector_double[DIM_VECTOR_DOUBLE];

<Asignacion de valores a los vectores>

ImprimeVector(vector_int, 3); // Correcto. Tipos iguales

ImprimeVector(vector_double, 3); // Error de compilación

}

Solución. Definiremos un procedimiento por cada tipo de dato

void ImprimeVectorInt (const int v[], int util_v){

for (int i=0; i<util_v; i++)

cout << v[i] << endl;

}

void ImprimeVectorDouble (const double v[], int util_v){

for (int i=0; i<util_v; i++)

cout << v[i] << endl;

}

Nota. C++ permite el uso de sobrecargas para evitar este problema.

Page 30: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 30

4.1.5. ALGORITMOS DE BÚSQUEDA

Al proceso de encontrar un elemento específico en un vectorse denomina búsqueda.

Búsqueda secuencial. Técnica más sencilla.

Búsqueda binaria. Técnica más eficiente, aunque requiereque el vector esté ordenado.

4.1.5.1. BÚSQUEDA SECUENCIAL

El vector no se supone ordenado.

Como no se modifica, se pasa como const <TipoBase> v[]

Devuelve la posición dónde se encuentra o un valor impo-sible de índice si no se encuentra (por ejemplo, -1)

Page 31: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 31

#include <iostream>

using namespace std;

void LecturaVectorDouble (double v[], int util_v);

int BuscaSec(const double v[], int util_v, double buscado);

int main(){

const int DIM_VECTOR = 10;

double vector[DIM_VECTOR];

int util_vector = 5;

int posicion;

LecturaVectorDouble (vector, util_vector);

cin >> encontrar;

posicion = BuscaSec(vector, util_vector, encontrar);

if (posicion == -1)

cout << "\nEl valor " << encontrar

<< "no se encuentra en el vector";

else

cout << "\nEl valor " << encontrar

<< "se encuentra en la posici\’on " << posicion;

}

<Definicion de funciones>

Page 32: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 32

Algoritmo:

Repite mientras !encontrado y tengas componentes v[i]

if v[i] == buscado

encontrado = true

else

i++

if encontrado

imprime posicion :-((

else

imprime "no se encuentra" :-((

Algoritmo:

Repite mientras !encontrado y tengas componentes v[i]

if v[i] == buscado

encontrado = true

else

i++

if encontrado

return i

else

return -1

Page 33: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 33

Primera aproximación.

int BuscaSec(const double v[], int util_v, double buscado){

int i, posicion;

bool encontrado;

i=0;

encontrado=false;

while ((i<util_v) && !encontrado)

if (v[i] == buscado){

posicion=i;

encontrado=true;

}

else

i++;

if (encontrado)

return posicion;

else

return -1;

}

Page 34: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 34

Segunda aproximación.

int BuscaSec(const double v[], int util_v, double buscado){

int i;

for (i=0; i<util_v && v[i]!=buscado; i++)

;

if (i==util_v)

return -1;

else

return i;

}

Page 35: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 35

A veces, podemos estar interesados en buscar entre una com-ponente izquierda y otra derecha, ambas inclusive.

int BuscaSec_entre (double v[], int izda, int dcha,

double buscado){

int i;

bool encontrado = false;

for (i=izda ; i<=dcha && !encontrado ; i++)

encontrado = (v[i]==buscado);

if (encontrado)

return i-1;

else

return -1;

}

Page 36: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 36

4.1.5.2. BÚSQUEDA BINARIA

Precondición Búsqueda Binaria: Se aplica sobre un vectorordenado.

La cabecera no cambia.

int BuscaBinaria(const double v[], int util_v,

double buscado)

Nota. El nombre del identificador de la función refleja queno es una búsqueda cualquiera, sino que necesita una pre-condición.

Algoritmo:

• El elemento a buscar se compara con el elemento queocupa la mitad del vector.

• Si coinciden, se habrá encontrado el elemento.

• En otro caso, se determina la mitad del vector en la quepuede encontrarse.

• Se repite el proceso con la mitad correspondiente.

Page 37: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 37

Ejemplo. Buscar el 40

60402518

5 6 7 8

dch=8izq=5

centro=6

6040

7 8

dch=8izq=7

centro=7

0 1 2 3 4 5 7 86

−8 60402518124 5 9

centro=4

dch=8izq=0

40 > 25

40 > 12

Encontrado

Page 38: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 38

int BuscaBinaria(const double v[], int util_v,

double buscado) {

int izq, dch, centro;

izq = 0;

dch = util_v-1;

centro = (izq+dch)/2;

while ((izq<=dch) && (v[centro]!=buscado)) {

if (buscado < v[centro])

dch = centro-1;

else

izq = centro+1;

centro = (izq+dch)/2;

}

if (izq>dch)

return -1;

else

return centro;

}

Page 39: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 39

4.1.6. CONSTRUCCIÓN DE VECTORES EN UNA FUN-CIÓN

Supongamos que queremos que un módulo construya un vec-tor. Éste no puede ser local ya que al terminar el módulo suzona de memoria desaparece.

Debemos declarar dicho vector en el main (en general, en lafunción que realiza la llamada) y pasarlo como parámetro:

Ejemplo. Crear un vector con las componentes pares de otro.

#include <iostream>

using namespace std;

void LecturaVectorInt (int v[], int util_v);

void ImprimeVectorInt (int v[], int util_v);

void SoloPares(const int v[], int util_v, int vPares[],

int &util_vPares);

int main(){

const int DIM=100;

int vector[DIM], salida[DIM];

int util_vector = 7, util_salida;

LecturaVectorDouble(vector, util_vector);

SoloPares(vector, util_vector, salida, util_salida);

ImprimeVectorDouble(salida, util_salida);

}

Page 40: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 40

<Definicion de LecturaVectorInt e ImprimeVectorInt>

void SoloPares(const int v[], int util_v, int vPares[],

int &util_vPares){

util_vPares=0;

for (int i=0; i<util_v; i++)

if ((v[i]%2) == 0){

vPares[util_vPares]=v[i];

util_vPares++;

}

}

Page 41: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 41

Ejemplo. Quitar los elementos repetidos de un vector, guardan-do el resultado en otro vector.

#include <iostream>

using namespace std;

void QuitaRepetidos (const double original[],

int util_original,

double destino[],

int &util_destino);

void LecturaVectorDouble (double v[], int util_v);

void ImprimeVectorDouble (double v[], int util_v);

int main(){

const int DIM =100;

int vector[DIM], salida[DIM], util_vector = 7, util_salida;

LecturaVectorDouble(vector, util_vector);

QuitaRepetidos(vector, util_vector, salida, util_salida);

ImprimeVectorDouble(salida, util_salida);

}

<Definicion de funciones>

Page 42: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 42

Algoritmo:

destino[0]=original[0]

Recorrer todas las componentes i de original

Si original[i] se encuentra en destino

i++

Si no

Añadir original[i] a destino

Incrementar util_destino

i++

Como se repite i++, podemos sacarlo del condicional. Por lotanto, el primero se queda vacío, y rescribimos el algoritmocomo sigue:

destino[0]=original[0]

Recorrer todas las componentes i de original

Si original[i] NO se encuentra en destino

Añadir original[i] a destino

Incrementar util_destino

i++

Page 43: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 43

void QuitaRepetidos (const double original[],

int util_original,

double destino[],

int &util_destino){

bool encontrado;

util_destino = 0;

for (int i=0 ; i<util_original ; i++){

encontrado = false;

for (int j=0 ; (j<util_destino) && !encontrado ; j++){

if (original[i] == destino[j])

encontrado = true;

}

if (!encontrado){

destino[util_destino] = original[i];

util_destino++;

}

}

}

Page 44: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 44

4.1.7. TRABAJANDO CON VECTORES LOCALES

Ejemplo. Calculad la moda de un vector de enteros, es decir,el elemento que más se repite. La moda de (4,2,1,2,3,2,5,1)

sería el 2.Para hacer los cómputos, vamos a usar un vector de repetidos.¿Cómo declaramos el vector local repetidos?

a) double Moda(double v[], int util_v){

double repetidos[util_v];

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

Imposible: no podemos dimensionar con una variable.

b) double Moda(double v[], int util_v){

const int DIM = util_v;

double repetidos[DIM];

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

Imposible: no podemos inicializar una constante con unavariable.

c) double Moda(double v[], int util_v){

double repetidos[100];

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

¿y por qué no 200?

Page 45: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 45

d) double Moda(double v[], int util_v){

double repetidos[DIM];

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

}

int main(){

const int DIM = 100;

double vector[DIM];

.......

}

Error de compilación. DIM no se conoce dentro de Moda

e) const int DIM = 100;

double Moda(double v[], int util_v){

double repetidos[DIM];

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

}

int main(){

double vector[DIM];

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

}

Es la única solución.

Inconveniente: no podemos separar la definición de Moda

de la definición de la constante global DIM.

Solución: se verá cuando veamos memoria dinámica.

Page 46: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 46

Vamos a calcular el conteo de la moda (su frecuencia) en lamisma función:

#include <iostream>

using namespace std;

const int DIM = 20;

void ModaVector(double v[], int util_v,

double &moda, int &conteo_moda);

int main(){

double notas[DIM] = {1,2,4,2,3,2,5,5,5,2};

double moda_notas;

int conteo_moda_notas;

ModaVector(notas, 10, moda_notas, conteo_moda_notas);

cout << moda_notas << " - " << conteo_moda_notas;

}

<Definicion de ModaVector>

Algoritmo.El vector local repetidos, se usa para almacenar las compo-nentes que ya se han recorrido

Recorrer todos los elementos v[i] del vector

Si v[i] no esta en repetidos => contamos las

apariciones de v[i] en v (desde i hacia la dcha)

Si v[i] esta en repetidos => ya lo hemos procesado.

No hacemos nada

Page 47: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 47

void ModaVector(double v[], int util_v,

double &moda, int &conteo_moda){

double repetidos[DIM];

int pos_enc, conteo_parcial, util_repetidos;

bool seguir;

repetidos[0] = v[0]; moda = v[0]; conteo_moda = 1;

util_repetidos = 1;

for (int i=1 ; i<util_v ; i++){

if (-1 == BuscaSec_entre (repetidos, 0,

util_repetidos-1, v[i])){

util_repetidos++;

seguir=true; conteo_parcial = 0; pos_enc = i;

while (seguir){

pos_enc = BuscaSec_entre(v, pos_enc+1,

util_v-1, v[i]);

if (-1==pos_enc)

seguir = false;

else

conteo_parcial++;

}

if (conteo_parcial > conteo_moda){

conteo_moda = conteo_parcial;

moda = v[i];

}

}

}

}

Page 48: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 48

4.1.8. ALGORITMOS DE ORDENACIÓN

La ordenación es un procedimiento mediante el cual se dispo-nen los elementos de un vector en un orden especificado, talcomo orden alfabético u orden numérico.

Existen dos tipos de ordenación:

Ordenación interna. Todos los datos están en memoria prin-cipal durante el proceso de ordenación.

• Inserción.

• Selección.

• Intercambio.

Ordenación externa. Parte de los datos a ordenar están enmemoria externa mientras que otra parte está en memoriaprincipal siendo ordenada. Se verán en MP2.

Page 49: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 49

4.1.8.1. ORDENACIÓN POR SELECCIÓN

Ejemplo. Calcular el mínimo elemento de un vector.

v = (2,4,7,1,8,?,?,?)

Mejor que devolver el elemento 1, devolvemos su posición 3

Algoritmo:

Inicializar minimo = v[0]

Recorrer todas las componentes v[i] (i>0)

Si v[i] es menor que minimo

Actualizar minimo

Recordar posicion

i++

int PosMinimo (const double v[], int util_v){

int posicion_minimo;

double minimo;

minimo = v[0];

posicion_minimo = 0;

for (int i=1; i<util_v ; i++)

if (v[i] < minimo){

minimo = v[i];

posicion_minimo = i;

}

return posicion_minimo;

}

Page 50: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 50

Ejemplo. Calcular el mínimo elemento de un vector, pero pa-sándole al módulo las componentes izda y dcha donde se quie-re trabajar.

v = (6,8,7,2,4,9,3,1,?,?) izda=2 , dcha=5

PosMinimo(v,izda,dcha) devuelve la posición 3 (índice de v)

Precondición: 0 <= izda <= dcha <= util_v-1

int PosMinimo (const double v[], int izda, int dcha){

int posicion_minimo;

double minimo;

minimo = v[izda];

posicion_minimo = izda;

for (int i=izda+1 ; i <= dcha ; i++)

if (v[i] < minimo){

minimo = v[i];

posicion_minimo = i;

}

return posicion_minimo;

}

Page 51: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 51

Ordenación por selección.

En cada pasada, se selecciona el elemento más pequeño delsubvector no ordenado y se intercambia con el primer elemen-to de este mismo subvector.

SubvectorOrdenado

SubvectorNo Ordenado

0 j k Util−1

Menor elemento de k a Util−1

Algoritmo:

Recorrer todos los elementos v[i] de v

Hallar la posicion pos_min del menor elemento

del subvector delimitado por las componentes

[i,util_v-1] ¡ambas inclusive!

Intercambiar v[i] con v[pos_min]

En el bucle principal no es necesario recorrer todos los ele-mentos de v, ya que si sólo queda 1 componente el vector es-tá ordenado. Por lo tanto, el bucle principal será de la formai<util_v-1

Page 52: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 52

7823 45 8 32 56

8 23 3245 78 56

238 32 78 45 56

8 5623 32 45 78

8 7823 32 45 56

8 45 23 32 5678

Tras la pasada 5

Tras la pasada 4

Tras la pasada 3

Tras la pasada 2

Tras la pasada 1

Vector Original

Page 53: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 53

#include <iostream>

using namespace std;

void ImprimeVectorDouble(double v[], int util_v){

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

}

void LecturaVectorDouble (double v[], int util_v){

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

}

int PosMinimo (const double v[], int izda, int dcha){

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

}

void IntercambiaDouble (double &a, double &b){

double aux;

aux = a;

a = b;

b = aux;

}

void OrdSeleccion (double v[], int util_v){

int pos_min;

for (int i=0 ; i<util_v-1 ; i++){

pos_min = PosMinimo(v, i, util_v-1);

IntercambiaDouble(v[i],v[pos_min]);

}

}

Page 54: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 54

int main(){

double vector[] = {7,4,8,1};

int util_vector = 4;

LecturaVectorDouble(vector, util_vector);

OrdSeleccion (vector, util_vector);

ImprimeVectorDouble(vector, util_vector);

}

Page 55: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 55

Versión sin llamadas a funciones:

void OrdSeleccion(double v[], int util_v){

int i, j, pos_min;

double aux;

for (i=0; i<util_v-1; i++){

pos_min=i;

for (j=i+1; j<util_v; j++)

if (v[j] < v[pos_min])

pos_min=j;

aux = v[i];

v[i] = v[pos_min];

v[pos_min] = aux;

}

}

Compromiso reutilización versus eficiencia. Usualmente pre-valecerá la reutilización. Pero si tenemos que construir un mó-dulo, verificando alguna de estas restricciones:

que realice muchas operaciones

que sea utilizable en otros programas

merece la pena construirlo eficientemente.

Page 56: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 56

4.1.8.2. ORDENACIÓN POR INSERCIÓN

Ejemplo. Insertar un elemento en una posición concreta de unvector.

v = (2,7,4,8,1,?,?,?)

pos_insercion = 3

valor = 5

v = (2,7,4,5,8,1,?,?)

Algoritmo (primera versión):

Recorrer las componentes posteriores a pos_insercion

hasta llegar al final de v

v[i] = v[i-1];

i++;

v[pos_insercion] = valor;

Algoritmo (versión correcta):

Recorrer las componentes desde el final del vector

hasta llegar a pos_insercion

v[i] = v[i-1];

i--;

v[pos_insercion] = valor;

Page 57: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 57

Parametrización:

void Inserta(double v[], int &util_v,

int pos_insercion, double valor)

Importante:

Hay que incrementar util_v en 1. Por eso se pasa por re-ferencia.

Precondición: util_v < DIM_V

void Inserta(double v[], int &util_v,

int pos_insercion, double valor){

for (int i=util_v ; i>pos_insercion ; i--)

v[i] = v[i-1];

v[pos_insercion] = valor;

util_v++;

}

int main(){

const int DIM_VECTOR = 8;

double vector[DIM_VECTOR] = {2,7,4,8,1};

int util_vector = 5;

Inserta(vector, util_vector, 3, 5);

}

Page 58: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 58

Supongamos que queremos quitar la precondiciónutil_v < DIM_V

Posibles soluciones:

Declarar DIM_V como una constante global y comprobar suvalor dentro del módulo Inserta

const int DIM_VECT = 100;

void Inserta(double v[], int &util_v, int pos_insercion,

double valor, bool &error){

error = (util_v >= DIM_VECT);

if (!error){

for (int i=util_v ; i>pos_insercion ; i--)

v[i] = v[i-1];

v[pos_insercion] = valor;

util_v++;

}

}

int main(){

int vect[DIM_VECT];

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

Inserta(vect, util_vect, 3, 5, err);

if (err)

cout << "Número de componentes insuficiente}

else

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

}

Page 59: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 59

Pasar la dimensión como parámetro a Inserta

void Inserta(double v[], int DIMEN, int &util_v,

int pos_insercion, double valor, bool &error){

error = (util_v >= DIMEN);

if (!error){

for (int i=util_v ; i>pos_insercion ; i--)

v[i] = v[i-1];

v[pos_insercion] = valor;

util_v++;

}

}

int main(){

const int DIM_VECT = 100;

int vect[DIM_VECT];

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

Inserta(vect, DIM_VECT, util_vect, 3, 5, err);

if (err)

cout << "Número de componentes insuficiente}

else

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

}

Page 60: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 60

En la primera solución no podemos separar la definición de lafunción de la constante. En la segunda, aumentamos el núme-ro de parámetros.

Posiblemente, lo mejor sea olvidarnos de la precondición yusar la cabecera:

void Inserta(double v[], int &util_v,

int pos_insercion, double valor)

Ejercicio: Borrad un elemento de un vector.

Page 61: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 61

Ejemplo. Insertad un elemento de forma ordenada en un vectorya ordenado.

v = (1,2,4,7,8,?,?,?)

valor = 5

v = (1,2,4,5,7,8,?,?)

Hay que desplazar componentes como en el ejemplo ante-rior.

La condición de parada cambia.

Algoritmo:

Recorrer las componentes desde el final del vector

hasta llegar a una componente que sea menor que el valor

v[i] = v[i-1];

i--;

v[i] = valor;

Page 62: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 62

void InsertaOrd(double v[], int &util_v, int valor){

int i;

for (i=util_v; i>0 && valor<v[i-1]; i--)

v[i]=v[i-1];

v[i]=valor;

util_v++;

}

Ejercicio. Cread un módulo para leer 100 elementos desde te-clado, y conforme los va leyendo, vaya creando un vector or-denado.

Page 63: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 63

Ordenación por inserción.

El vector se divide en dos subvectores: el de la izquierda orde-nado, y el de la derecha desordenado.

Cogemos el primer elemento del subvector desordenado y loinsertamos de forma ordenada en el subvector ordenado.

SubvectorOrdenado

SubvectorNo Ordenado

0 j k Util−1

INSERTAR

Importante. La componente de la posición k (primer elemen-to del subvector desordenado) será remplazada por la anterior(después de desplazar).

Algoritmo.

Ir fijando el inicio del subvector izquierda

con un contador izda desde 1 hasta util_v

Seleccionar el valor v[izda]

Insertar dicho valor de forma ordenada

en el subvector de v delimitado por [0,izda-1]

Nota. Empezamos desde 1, ya que la primera componente for-ma un subvector ya ordenado.

Page 64: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 64

45 8 32 56

23 5678 8 32

56

8 78

45

23 45 78 8 32 56

8 23 45 78 32 56

8 23 32 45 78

23 32 45 56

23 78 Vector Original

Tras la pasada 1

Tras la pasada 2

Tras la pasada 3

Tras la pasada 4

Tras la pasada 5

Page 65: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 65

void OrdInsercion (double v[], int util_v){

int izda;

double valor;

for (izda=1; izda<util_v; izda++){

valor = v[izda];

InsertaOrd(v, izda, valor); // <- Modifica v[izda]!

}

}

Obviamente, no es necesaria la variable valor:

void OrdInsercion (double v[], int util_v){

int izda;

for (izda=1; izda<util_v; izda++)

InsertaOrd(v, izda, v[izda]);

}

Page 66: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 66

Sin embargo, el algoritmo no funciona correctamente!Razón: izda se pasa por referencia y en cada iteración se mo-difica en la llamada a InsertaOrd.

Solución:

void OrdInsercion (double v[], int util_v){

int izda = 1;

while (izda < util_v)

InsertaOrd(v, izda, v[izda]);

}

Sin llamadas a funciones:

void OrdInsercion (double v[], int util_v){

int izda, i;

double valor;

for (izda=1; izda<util_v; izda++){

valor = v[izda];

for (i=izda; i>0 && valor<v[i-1]; i--)

v[i] = v[i-1];

v[i] = valor;

}

}

Page 67: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 67

4.1.8.3. ORDENACIÓN POR INTERCAMBIO DIRECTO (MÉTODO DE

LA BURBUJA)

Al igual que antes, a la izquierda se va dejando un subvectorordenado.

Desde el final y hacia atrás, se van comparando elementos dosa dos y se deja a la izquierda el más pequeño (hay que inter-cambiarlos).

Page 68: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 68

Ejemplo (Primera Pasada)

7823 45 8 32 56

7823 45 8 32 56

7823 45 8 32 56

23 32 5645788

32 5645788 23

No intercambiar

No intercambiar

Intercambiar

Vector Original

7823 32 568 45

Intercambiar

Intercambiar

Proceso

Durante Pasada 1

Tras la pasada 1

Page 69: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 69

Ejemplo (Resto de Pasadas)

8 7823 32 45 56

8

7823 45 8 32 56

8 23

238 32

8 23 32 45

32 78 45 56

7845 56

56 78

23 78 45 32 56

Tras la pasada 5

Tras la pasada 4

Tras la pasada 3

Tras la pasada 2

Tras la pasada 1

Vector Original

Page 70: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 70

Algoritmo

Ir fijando el inicio del subvector izquierda

con un contador izda desde 0 hasta util_v

Recorrer el vector de la derecha desde

el final (util_v) hasta el principio (izda)

con un contador i

Si v[i] < v[i-1] intercambiarlos

SubvectorOrdenado

SubvectorNo Ordenado

0 j k Util−1

El menor se desplaza hacia k

Page 71: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 71

Primera Aproximación

void OrdBurbuja (double v[], int util_v){

int izda, i;

for (izda=0; izda<util_v; izda++)

for (i=util_v-1 ; i>izda ; i--)

if (v[i] < v[i-1])

IntercambiaDouble(v[i], v[i-1]);

}

Mejora. Si en una pasada del bucle más interno no se produceningún intercambio, el vector ya está ordenado. Lo comproba-mos con una variable lógica.

Page 72: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 72

Segunda Aproximación

void OrdBurbuja (double v[], int util_v){

int izda, i;

bool cambio;

cambio= true;

for (izda=0; izda<util_v && cambio; izda++){

cambio=false;

for (i=util_v-1 ; i>izda ; i--)

if (v[i] < v[i-1]){

IntercambiaDouble(v[i], v[i-1]);

cambio=true;

}

}

}

Page 73: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 73

4.1.9. CADENAS DE CARACTERES (CSTRING)

4.1.9.1. INTRODUCCIÓN

Una cadena de caracteres es un secuencia ordenada de carac-teres de longitud variable. Permiten trabajar con datos comoapellidos, direcciones, etc. Recordemos que los literales de ca-dena de caracteres se representan entre comillas dobles.

cout << "Esto es un literal de cadena de caracteres";

En C++ podemos encontrar dos alternativas para representareste tipo de información:

El tipo string que son las cadenas de caracteres propias deC++ que se introdujeron en el primer tema y se verán conmás detalle en MP2.

string mensaje;

mensaje = "Esto es un literal de cadena de caracteres";

cout << mensaje;

Un vector de char. Es la forma heredada de C.

char mensaje[10];

Para delimitar el final del vector NO se usa la típica varia-ble util_mensaje sino un carácter especial ’\0’ que se leasignará a la última componente.’\0’ se conoce como marca de fin de cadena o carácternulo

Page 74: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 74

La asignación se realiza componente a componente, como cual-quier otro vector.

char mensaje[10];

mensaje[0] = ’H’;

mensaje[1] = ’o’;

mensaje[2] = ’l’;

mensaje[3] = ’a’;

mensaje[4] = ’\0’;

mensaje = "Hola"; // <- Error de compilación.

// mensaje es un vector !!

’H’ ’o’ ’l’ ’a’ ’\0’ ? ? ? ? ?

A los vectores de char con el carácter nulo como terminador seles suele llamar cstring (pero no es un tipo propio del lenguaje)

En general, declararemos:

char <identificador> [<tamaño>];

dónde el tamaño ha de ser el número de caracteres más uno(para almacenar el carácter nulo)

char mensaje[4];

mensaje[0] = ’H’;

mensaje[1] = ’o’;

mensaje[2] = ’l’;

mensaje[3] = ’a’;

mensaje[4] = ’\0’; // Error lógico :-(

Page 75: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 75

char mensaje[5];

mensaje[0] = ’H’;

mensaje[1] = ’o’;

mensaje[2] = ’l’;

mensaje[3] = ’a’;

mensaje[4] = ’\0’; // :-)

4.1.9.2. INICIALIZACIÓN Y ASIGNACIÓN

Al declarar un cstring, podemos darle un valor inicial comocualquier otro vector:

char mensaje[5] = {’H’,’o’,’l’,’a’,’\0’};

char no_cabe[4] = {’H’,’o’,’l’,’a’,’\0’}; // Warning o error

Incluso podemos suprimir la dimensión (esto es válido paracualquier vector, siempre que lo inicialicemos en la declara-ción)

char mensaje[] = {’H’,’o’,’l’,’a’,’\0’};

El compilador reserva automáticamente 5 componentes.

Para los vectores de char, C++ permite inicializarlos con unliteral de cadena de caracteres:

char mensaje[5] = "Hola";

char mensaje[] = "Hola";

char no_cabe[4] = "Hola"; // <- Warning o error

El compilador pondrá automáticamente el carácter nulo al final.

Page 76: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 76

Esta asignación sólo puede hacerse en la inicialización:

char mensaje[5] = "Hola";

char otro_mensaje[5];

otro_mensaje = "Hola"; // Error de compilación

// vector = literal cadena caracteres

otro_mensaje = mensaje; // Error de compilación

// Asignación entre vectores

4.1.9.3. USO DE FUNCIONES

Como cualquier otro vector (salvo que no pasamos las compo-nentes útiles)

int longitud(const char cadena[]){

int i=0;

while (cadena[i]!=’\0’);

i++;

return i;

}

int main(){

char mensaje[] = "Hola";

cout << longitud(mensaje); // Imprime 4

}

Page 77: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 77

Ejercicio: Construir una función que dada una cadena s y uncarácter c devuelva la posición que ocupa la primera ocurren-cia del carácter c en la cadena s. Devolver -1 si el carácter noestá en la cadena.

Page 78: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 78

4.1.9.4. OPERADOR DE ASIGNACIÓN ENTRE CSTRING

char mensaje[5] = "Hola";

char otro_mensaje[5];

otro_mensaje = mensaje; // Error de compilación

// Asignación entre vectores!!

void CopiaCadena(char destino[], const char origen[]){

for (int i=0 ; v[i]!=’\0’; i++)

destino[i] = origen[i];

}

int main(){

char mensaje[5] = "Hola";

char otro_mensaje[5];

CopiaCadena(otro_mensaje, mensaje); // :-)

.....

}

int main(){

char mensaje[5];

char otro_mensaje[5];

mensaje[0] = ’H’;

CopiaCadena(otro_mensaje, mensaje); // Error lógico grave

Page 79: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 79

La biblioteca (cstring) contiene la definición de ésta y muchasotras funciones para trabajar con vectores de char.

strcpy(char cadena1, const char cadena2);

#include <cstring>

int main(){

char mensaje[5] = "Hola";

char otro_mensaje[5];

strcpy(otro_mensaje, mensaje);

.....

}

IMPORTANTE: Es tarea del programador asegurar que el tama-ño de la cadena destino es suficiente para realizar la copia dela cadena fuente.

Otras funciones de la biblioteca cstring:

int strlen(const char s[]) que devuelve la longitud de lacadena s.

strcat(char s1[], const char s2[]) que concatena las ca-denas s1 y s2 y el resultado se almacena en s1.

int strcmp(const char s1[], const char s2[]) que compa-ra las cadenas s1 y s2. Si la cadena s1 es menor que s2 de-vuelve un valor menor que cero, si son iguales devuelve 0y en otro caso devuelve un valor mayor que cero.

Page 80: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 80

4.1.9.5. LECTURA DE CADENAS CSTRING

Se pueden utilizar las operaciones de lectura y escritura yaconocidas:

char nombre[30];

cout << "Introduce tu nombre: ";

cin >> nombre;

cout << "El nombre introducido es: " << nombre;

Sin embargo, si la cadena que se desea introducir contieneseparadores (espacios y/o tabuladores), la variable contendrásólo los caracteres hasta el primer separador.

Si se desea introducir una cadena con estos separadores esnecesario hacerlo usando:

cin.getline (<buffer>,<longitud>)

donde <buffer> es un vector de char y <longitud> es el espaciodisponible en el vector.

Page 81: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 81

const int TAMANO=30; char nombre[TAMANO];

int edad;

char direccion[TAMANO];

cout << "Introduce tu nombre: ";

cin.getline (nombre,TAMANO);

cout << "El nombre introducido es: " << nombre;

cout <<"Introduce tu edad: ";

cin >> edad;

cout <<"Introduce tu direccion: ";

cin.getline(direccion,TAMANO);

...

Problema: Cuando se lee edad se queda el salto de linea en elbuffer y cin.getline (direccion,TAMANO) lee ese salto de líneay, como ya ha leido un salto de línea, termina y devuelve lacadena vacia.

Page 82: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 82

Solución: Crear una función LeerLinea que evite las líneas va-cías:

void LeerLinea(char c[], int maxlongitud)

{

do {

cin.getline(c,maxlongitud);

} while (c[0]==’\0’); // evita las cadenas vacias

}

...

cout << "Introduce tu nombre: ";

LeerLinea (nombre,TAMANO);

cout << "Introduce tu edad: ";

cin >> edad;

cout << "Introduce tu direccion: ";

LeerLinea (direccion,TAMANO); ...

Page 83: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 83

4.2. MATRICES

4.2.1. INTRODUCCIÓN

4.2.1.1. MOTIVACIÓN

Supongamos una finca rectangular dividida en parcelas. Que-remos almacenar la producción de aceitunas, en TM.

La forma natural de representar la parcelación sería usando elconcepto matemático de matriz.

4.5 5.9 1.2

9.1 0.4 5.8

Para representarlo en C++ podríamos usar un vector parcela:

9.1 0.4 5.8 4.5 5.9 1.2

pero la forma de identificar cada parcela (por ejemplo parcela[4])es poco intuitiva para el programador.

Page 84: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 84

4.2.1.2. DECLARACIÓN DEL TIPO MATRIZ

<tipo de dato> <identificador> [DIM_FIL][DIM_COL];

Como con los vectores, el tipo base de la matriz es el mismopara todas las componentes, ambas dimensiones han de serde tipo entero, y comienzan en cero.

int main(){

const int DIM_FIL_parcela = 2;

const int DIM_COL_parcela = 3;

double parcela[DIM_FIL_parcela][DIM_COL_parcela];

}

Page 85: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 85

4.2.1.3. INICIALIZACIÓN

Al igual que con los vectores, podemos inicializar una matrizen la misma declaración. La forma segura es poner entre llaveslos valores de cada fila.

int m[2][3]={{1,2,3},{4,5,6}}; // m tendra: 1 2 3

// 4 5 6

Si no hay suficientes inicializadores para una fila determinada,los elementos restantes se inicializan a 0.

int mat[2][2]={{1},{3,4}}; // Mat tendra: 1 0

// 3 4

Si se eliminan los corchetes que encierran cada fila, se iniciali-zan los elementos de la primera fila y después los de la segun-da, y así sucesivamente.

int A[2][3]={1, 2, 3, 4, 5} // A tendra: 1 2 4

// 4 5 0

Page 86: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 86

4.2.2. OPERACIONES CON MATRICES

4.2.2.1. ACCESO

<Ident> [<ind1>] [<ind2>]

0 ≤ indi < Dimi

<Ident> [<ind1>] [<ind2>] es una variable más del programa yse comporta como cualquier variable del tipo de dato base dela matriz.

4.2.2.2. ASIGNACIÓN, LECTURA Y ESCRITURA

En la declaración de la matriz se pueden asignar valores a todala matriz. Posteriormente, no es posible: es necesario accedera cada componente independientemente.

Por ejemplo, para asignar una expresión a una celda:

<Ident> [<ind1>] [<ind2>] = <Expresión>;

<Expresión> ha de ser del mismo tipo de dato que el tipo basede la matriz.

Page 87: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 87

Ejemplo:

int main(){

const int DIM_FIL_parcela = 2;

const int DIM_COL_parcela = 3;

double parcela[DIM_FIL_parcela][DIM_COL_parcela];

int valor = 7;

parcela[0][0] = 4.5 // Correcto;

parcela[0][1] = 5.9 // Correcto;

parcela[2][0] = 7.2 // Error logico: Fila 2 No existe.

parcela[0][3] = 7.2 // Error logico: Columna 3 No existe.

parcela[0][0] = 4 // Correcto:

// Casting automatico: double=int

}

Page 88: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 88

4.2.3. GESTIÓN DE COMPONENTES ÚTILES CON MA-TRICES

Por cada dimensión necesitamos gestionar una variable queindique el número de componentes útiles.

#include <iostream>

using namespace std;

int main(){

const int DIM_FIL_parcela=5, DIM_COL_parcela=8;

int utilFil_parcela, utilCol_parcela;

int fil, col;

double parcela[DIM_FIL_parcela][DIM_COL_parcela];

double produccion;

utilFil_parcela=2;

utilCol_parcela=3;

for (fil=0 ; fil<utilFil_parcela ; fil++)

for (col=0 ; col<utilCol_parcela ; col++){

cout << "Introduce produccion en TM de la parcela "

<< fil << "," << col;

cin >> produccion;

parcela[fil][col]= produccion;

}

cout << "\nDatos introducidos:\n";

Page 89: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 89

for (fil=0 ; fil<utilFil_parcela ; fil++){

for (col=0 ; col<utilCol_parcela ; col++){

cout << "\nProducci\’on en TM de la parcela "

<< fil << "," << col << " --> ";

cout << parcela[fil][col];

}

cout << endl;

}

}

Nota. Podemos poner directamente: cin >> parcela[fil][col]

Page 90: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 90

Ejemplo. Buscar un elemento en una matriz.

#include <iostream>

using namespace std;

int main(){

const int DIM_FIL_m = 2, DIM_COL_m = 3;

double m[DIM_FIL_m][DIM_COL_m];

int Filencontrado, Colencontrado, utilFil_m,

utilCol_m, fil, col;

double buscado;

bool encontrado;

do{

cout << "Introducir el numero de filas: ";

cin >> utilFil_m;

}while ( (utilFil_m<1) || (utilFil_m>DIM_FIL_m) );

do{

cout << "Introducir el numero de columnas: ";

cin >> utilCol_m;

}while ( (utilCol_m<1) || (utilCol_m>DIM_COL_m) );

Page 91: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 91

for (fil=0 ; fil<utilFil_m ; fil++)

for (col=0 ; col<utilCol_m ; col++){

cout << "Introducir el elemento ("

<< fil << "," << col << "): ";

cin >> m[fil][col];

}

cout << "\nIntroduzca elemento a buscar: ";

cin >> buscado;

encontrado=false;

for (fil=0; !encontrado && (fil<utilFil_m) ; fil++){

for (col=0; !encontrado && (col<utilCol_m) ; col++)

if (m[fil][col] == buscado){

encontrado = true;

Filencontrado = fil;

Colencontrado = col;

}

}

}

if (encontrado)

cout << "\nencontrado en la posici\’on "

<< Filencontrado << "," << Colencontrado << endl;

else

cout << "\nElemento no encontrado\n";

}

Importante: la variable encontrado ha de ser la misma en losdos bucles while.

Page 92: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 92

4.2.4. MATRICES DE VARIAS DIMENSIONES

Podemos declarar tantas dimensiones como queramos. Sóloes necesario añadir más corchetes.

Por ejemplo, para representar la producción de una finca di-vidida en 2×3 parcelas, y dónde en cada parcela se practicancinco tipos de cultivos, definiríamos:

const int DIV_HOR = 2,

DIV_VERT = 3,

TOTAL_CULTIVOS = 5;

double parcela[DIV_HOR][DIV_VERT][TOTAL_CULTIVOS];

// Asignación al primer cultivo de la parcela 1,2

parcela[1][2][0] = 4.5;

Page 93: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 93

4.2.5. MODULARIZACIÓN CON MATRICES

Todas las posiciones de una matriz están realmente contiguasen memoria. La representación exacta depende del lenguaje.En C++ se hace por filas:

4.5 5.9 1.2

m

9.1 0.4 5.8

m

9.1 0.4 5.8 4.5 5.9 1.2

Para calcular dónde se encuentra la componente m[1][2] elcompilador debe pasar a la segunda fila. Lo consigue trasla-dándose tantas posiciones como diga DIM_COL_m, a partir delcomienzo de m. Una vez ahí, salta 2 posiciones y ya está enm[1][2].

Conclusión: Para saber dónde está m[i][j], el compilador ne-cesita saber cuánto vale DIM_COL_m, pero no DIM_FIL_m. Paraello, da tantos saltos como indique la expresión:

i*DIM_COL_m + j

Por eso, para pasar una matriz bidimensional hay que especi-ficar en la cabecera DIM_COL_m

void ImprimeMatriz(double m[][DIM_COL_m] , int utilFil_m,

int utilCol_m)

Page 94: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 94

Pero entonces, DIM_COL_m no puede ser local a main. Debe seruna constante global :-(. No hay otra solución.

#include <iostream>

using namespace std;

const int DIM_FIL=3, DIM_COL=2;

void ImprimeMatriz(const double m[][DIM_COL] , int utilFil,

int utilCol){

for (int fil=0 ; fil<utilFil ; fil++){

for (int col=0 ; col<utilCol ; col++)

cout << m[fil][col] << " ";

cout << endl;

}

}

int main(){

double parcela[DIM_FIL][DIM_COL]={{5.4,3},{6,7},{1,2.4}};

int utilFil_parcela=3, utilCol_parcela=2;

ImprimeMatriz(parcela , utilFil_parcela , utilCol_parcela);

}

Page 95: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 95

En general, para una matriz n-dimensional hay que especificartodas las dimensiones excepto la primera.

const int DIM_FIL=3, DIM_COL=2, DimProf=5;

void ImprimeMatriz(const double m[][DIM_COL][DimProf] ,

int utilFil, int utilCol, int utilProf){

for (int fil=0 ; fil<utilFil ; fil++){

for (int col=0 ; col<utilCol ; col++){

for (int prof=0 ; prof<utilProf ; prof++)

cout << m[fil][col][prof] << " ";

cout << endl;

}

cout << endl;

}

}

Importante: éste es un ejemplo de la necesidad de usar cons-tantes globales. Sin embargo, posiblemente sea el único casodonde lo hagamos.

Page 96: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 96

Ejemplo: Buscar un elemento en una matriz.

#include <iostream>

using namespace std;

const int DIM_FIL = 2; const int DIM_COL = 3;

void BuscaEnMatriz(const double m[][DIM_COL],

int utilFil, int utilCol,

double buscado, bool &encontrado,

int &fil_encontrado, int &col_encontrado){

int fil;

int col;

encontrado=false;

for (fil=0; !encontrado && (fil<utilFil) ; fil++){

for (col=0; !encontrado && (col<utilCol) ; col++)

if (m[fil][col] == buscado){

encontrado = true;

fil_encontrado = fil;

col_encontrado = col;

}

}

}

int main(){

double m[DIM_FIL][DIM_COL];

int fil, col, utilFil_m, utilCol_m,

posFil, posCol;

double elemento;

Page 97: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 97

bool encontrado;

do{

cout << "Introduce el numero de filas: ";

cin >> utilFil_m;

}while ( (utilFil_m<1) || (utilFil_m>DIM_FIL) );

do{

cout << "Introduce el numero de columnas: ";

cin >> utilCol_m;

}while ( (utilCol_m<1) || (utilCol_m>DIM_COL) );

for (fil=0; fil<utilFil_m; fil++)

for (col=0; col<utilCol_m; col++){

cout << "\nIntroduce el " << fil << "," << col <<": ";

cin >> m[fil][col];

}

cout << "\n\nIntroduzca elemento a buscar: ";

cin >> elemento;

BuscaEnMatriz(m, utilFil_m, utilCol_m, elemento,

encontrado, posFil, posCol);

if (encontrado)

cout << "\nEncontrado en la posición "

<< posFil << "," << posCol;

else

cout << "\nElemento no encontrado\n";

}

Page 98: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 98

Ejercicio. Calcular la traspuesta de una matriz.

Page 99: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 99

4.2.6. GESTIÓN DE FILAS DE UNA MATRIZ COMO VEC-TORES

Internamente, una matriz es una serie de posiciones contiguasen memoria. Como cada fila también es una serie de posicio-nes contiguas en memoria, podemos decir que una fila de unamatriz es un vector.

¿Cómo se llama la fila i de una matriz m? m[i]

Fila 0 -> m[0]

Fila 1 -> m[1]

Fila 2 -> m[2]

¿Cuántas componentes utilizadas tiene el vector m[i]? util_Col_m

Page 100: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 100

Ejemplo. Ordenar la fila 3 de una matriz bidimensional.

void OrdSeleccion (double v[], int util_v){

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

}

void ImprimeVector(const double vector[], int util_vector){

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

}

int main(){

double m[DIM_FIL][DIM_COL];

int utilFil_m, utilCol_m,

Filencontrado, Colencontrado;

<Rellenar datos de m>

OrdSeleccion (m[3],utilCol_m);

ImprimeVector(m[3],utilCol_m);

}

Nota. Obviamente, no ocurre lo mismo con las columnas deuna matriz.

Ejercicio. Supongamos que queremos ordenar todos los ele-mentos de una matriz. Por ejemplo:

3 5 7 1 2 3

2 1 9 --> 4 5 5

5 6 4 6 7 9

¿Qué condiciones se han de dar para poder llamar simplemen-te al procedimiento de ordenación de un vector en la formaOrdSeleccion(m[0],Tope)?

Page 101: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 101

Ejemplo. Hallar el máximo elemento de los mínimos de cadafila de una matriz.

3 5 7 3 |

2 1 9 --> 1 | --> 4

5 6 4 4 |

Primera aproximación.

Ordenar cada fila

Coger el primer elemento de cada fila

y calcular el maximo de todos ellos.

Inconvenientes:

No debemos modificar los datos originales de la matriz

Ordenar un vector es más lento que buscar el mínimo.

Segunda aproximación.

Calcular el minimo de cada fila y almacenarlo en

un vector de minimos

Calcular el maximo de dicho vector.

Notas:

El vector de mínimos tendrá tantas componentes como di-ga utilFil. Pero como no podemos dimensionar con unavariable tendremos que usar DIM_FIL

Usamos las funciones PosMinimo y PosMaximo, que ya cons-truimos en el apartado de Ordenación.

Debemos inicializar la primera componente del vector demínimos al mínimo de la primera fila.

Page 102: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 102

double MaxMin (const double m[][DIM_COL],

int utilFil, int utilCol){

double minimos[DIM_FIL]; // <- ¡DIM_FIL ha de ser global!

int pos_minimo, pos_maximo;

for (int fil=0 ; fil<utilFil ; fil++){

pos_minimo = PosMinimo(m[fil],utilCol);

minimos[fil] = m[fil][pos_minimo];

}

pos_maximo = PosMaximo(minimos,utilFil);

return minimos[pos_maximo];

}

Mejoras:

Modificar para devolver las posiciones (fila y columna) dón-de se alcanza el valor.

No necesitamos un vector de mínimos. Podemos ir calcu-lando el máximo de los mínimos poco a poco.

Page 103: C4Vectores2005 2006 VERSIONMIA - decsai.ugr.esdecsai.ugr.es/~lozano/mp1-0809/Vectores.pdfTema 4. Vectores y Matrices 2 TEMA 4. VECTORES Y MATRICES 4.1. VECTORES 4.1.1. MOTIVACIÓN

Tema 4. Vectores y Matrices 103

double MaxMin (const double m[][DIM_COL],

int utilFil, int utilCol){

double maximo, minimo;

int pos_minimo, pos_maximo;

pos_minimo = PosMinimo(m[0],utilCol);

maximo = m[0][pos_minimo];

for (int fil=1 ; fil<utilFil ; fil++){

pos_minimo = PosMinimo(m[fil],utilCol);

minimo = m[fil][pos_minimo];

if (minimo > maximo)

maximo = minimo;

}

return maximo;

}

Mejoras:

En cuanto encontremos un elemento de una fila menor queel máximo hasta ese momento, podemos parar la búsque-da en esa fila.

3 5 7 3

2 --> 2 < 3 => Parar la busqueda en esta fila

5 6 4 4