fundamentos de computación arreglos. objetivos aprender la importancia de los arreglos de datos, su...

39
Fundamentos de Computación Arreglos

Upload: esperanza-plaza-juarez

Post on 24-Jan-2016

239 views

Category:

Documents


0 download

TRANSCRIPT

  • Fundamentos de ComputacinArreglos

  • ObjetivosAprender la importancia de los arreglos de datos, su declaracin y manipulacin.Conocer cmo son almacenados en memoria.Aprender la aplicacin de la inicializacin esttica de arreglos.Conocer la estructura de arreglos multidimensionales.

  • IntroduccinConocemos los tipos de datos atmicos (int, double, char)Los tipos datos compuestos, por otro lado, estn formados por tipos datos atmicos: las cadenas (string) estn formados por caracteres (char).As mismo, se pueden crear otros tipos de datos mas complejos, usando tipos de datos compuestos.Este tipo de agrupacin, para crear nuevos tipos de datos, puede seguir hasta que se necesite.

  • Estructura de DatosSe puede considerar un conjunto de datos, Como una sola entidadComo un solo tipo de dato De esta forma, se reduce la complejidad de un problema.Un programa esta formado por:Estructuras de control y llamadas a funciones (el algoritmo de nuestro programa).Datos, con sus respectivos tipos, ya sean estos atmicos o complejos, juntos forman una jerarqua (la estructura de datos del programa).PROGRAMA = ALGORITMO + ESTRUCTURA DE DATOS

  • Qu es un Arreglo?Basndonos en los tipos de datos atmicos, podemos crear otros ms complejos.Un arreglo es una coleccin, o grupo de datos, donde:Cada dato tiene su posicin (primero, segundo, tercero)Y todos los datos del grupo son del mismo tipo, es decir, o todos son enteros, o todos son reales, etc.

    La mejor forma de visualizar un arreglo es:Como un grupo de cajas, una detrs de otra

    Donde cada caja representa un dato del arreglo o un elemento.Podemos concluir que un arreglo tiene:Tamao: cuantas cajas va a tener, el numero de datosTipo: cual es el tipo de todos los datos del arregloNombre: el nico nombre bajo el cual vamos a dirigirnos al mismo.Jams olvidar que un arreglo tiene un tipoNO EXISTEN ARREGLOS MEZCLADOS

  • Declaracin de ArreglosAl declarar una variable cualquiera siempre indicamos: tipo y nombre.Para declarar un arreglo, se debe indicarTipoNombre yTamaoUn arreglo de 10 elementos enteros, se declara:int ArregloEnteros[10];Y lo podemos visualizar:Cada elemento del grupo va a estar identificado por un valor numrico, llamado ndice. En C el primer elemento de un arreglo tiene el ndice 0.Siempre, para indicar el tamao de un arreglo, se utilizara un valor constante, jams una variable.Jams olvidar, el tamao de un arreglo es una constante

  • Manejo de ArreglosTenemos ahora 10 enteros bajo un mismo nombreComo accedemos a uno de esos datos?Usamos el nombre del arreglo y el ndice que identifica al elementonombre_arreglo[indice]Si se desea asignar el valor de 2 al primer elemento del arreglo:ArregloEntero[0] = 2;ArregloEntero[4] = 1:ArregloEntero[1] = 9;2Cada elemento es en efecto una variable del tipo declarado para el arregloEs muy importante no olvidar:El ndice de un elemento, no es el valor de dicho elementoEl ndice puede ser cualquier expresin que retorne un valor enteroPara asignar a todos los elementos del arreglo, un mismo valor, lo mas practico es usar un for:for(i = 0; i < 10; i++){ ArregloEntero[i] = 0}91

  • Leer e Imprimir un ArregloAcabamos de ver un ejemplo para acceder a todos los elementos de una arreglo de una forma practicaSi tenemos 10 elementos en un arreglo, y queremos pedir que los ingresen por teclado, debemos repetir el ingreso 10 veces:for(i = 0; i < 10; i++){ ArregloEnteros[i] = GetInteger();}As mismo, para imprimir todos los elementos de un arreglo, deberamos repetir el proceso de imprimir un, pero diez veces:for(i = 0; i < 10; i++){ printf(Elemento No. %d:%d\n,i+1,ArregloEnteros[i]);}

    ArregloEnteros[0] = GetInteger();ArregloEnteros[1] = GetInteger();ArregloEnteros[2] = GetInteger();....

  • EjercicioEscribir un programa que permita el ingreso de las notas de un curso de 20 alumnos. Una vez ingresados, debe mostrarse el promedio de las mismas.#define MAX_ALUMN 20

    main(){double Notas[MAX_ALUMN];double total, promedio;int i;total = 0;for(i = 0; i < MAX_ALUMN; i++){printf("Ingrese Alumno No %d:",i+1);Notas[i]=GetInteger();}for(i = 0; i < MAX_ALUMN; i++){total = total + Notas[i];}promedio = (double)total / (double)MAX_ALUMN;printf("Promedio: %.2f",promedio);}El usuario del programa no tiene porque saber que los ndices van desde 0, se le pueden mostrar desde 1

  • Representacin Interna de DatosEl ejercicio que acabamos de resolver es bastante sencillo.No tuvimos que aplicar refinamiento paso a paso.La clave del refinamiento es el uso de funciones, pero Cmo uso funciones y arreglos?, es decir, como una funcin puede recibir un arreglo?Antes de adentrarnos en ese tema debemos revisar como estn almacenados internamente los datos

  • Bits bytes y wordsEn el nivel ms primitivo estn los bits (binary digit), solo almacenan 0 o 1.Los bits son muy pequeos para contener informacin completa.Para poder almacenar informacin, se unen varios bits, y se manejan como una unidad.Los bytes son conjuntos de 8 bits, pero siguen siendo muy pequeos, apenas pueden almacenar un carcter.Los bytes se unen para formar las palabras(word)Una palabra, usualmente es del tamao suficiente para almacenar un valor entero.

  • Direcciones de MemoriaPara no perderse, la mquina le da una direccin numrica a cada uno de sus bytes.El primer byte tiene direccin 0, el segundo 1, y as.Al declarar una variable de tipo char, el computador buscar darle una direccin.char cchar c;No hay como saber la direccin que le dar el computador. Asumamos que es 1004.Si se le asigna un valor a la variable: c = A;El byte pasar a almacenar dicho valor. Ahora la direccin 1004 tiene el contenido 65.Valores mayores a un solo caracter, se deben almacenar en mas bytes. Estos bytes sern consecutivos.Si un entero toma dos bytes, estos tendrn direcciones consecutivas. int a;

  • Operador sizeofUn char ocupa un byte.Cuantos bytes ocupa un entero? un real? una cadena?Depende de cada mquinaPodemos averiguarlo usando el operador sizeof.sizeof(int) devuelve el nmero de bytes que necesita un dato de tipo int.CUIDADO: sizeof es un operador, no una funcin.

  • Reservar Espacio en MemoriaComo ya vimos, cuando se crea una variable, la computadora le asigna un espacio en memoria.Este acto se conoce como reservar memoria, o allocation(en ingls).Para las variables globales, la memoria se reserva cuando el programa comienza y se libera cuando este termina.Para las variables locales, la memoria se reserva cuando se entra en su ambiente y se libera cuando este termina(funciones).Si se declara un arreglo de 10 enteros, la computadora reserva memoria consecutiva para 10 variables, del tamao de los enteros.Consecutiva, quiere decir que los bytes reservados tienen todos direcciones una a continuacin de otra.Ejemplo: char ArregloChar[20];La computadora reserva 20 bytesdouble Puntaje[5];Si cada double requiere 8 bytes, la computadora reserva 40 bytes todos consecutivos.

  • Cuando Acceder a un Elemento ...En memoria, si queremos acceder a un elemento del arreglo PuntajeLa direccin base es la direccin del primer elemento del arreglo.El ajuste necesario para llegar a la direccin de un elemento dado se conoce como desfase.Cul es la direccin del elemento de ndice 2?R: 2*8+1000 = 1016Si se accede al elemento Puntaje[6], que pasara?Esta fuera del rango.Pero en memoria tendra, lgicamente, la direccin 6*8+1000= 1048.En la computadora existe un byte con esa direccin, pero no tendr precisamente lo que esperamos.Contendr basura.

  • Paso de Arreglos a FuncionesEscribir un programa que:Lea una lista de enteros hasta que se ingrese 0Reverse los elementos en la listaMuestre la lista invertidaPara resolver un problema con varios requerimientos podemos usar refinamiento paso a paso funcionesvoid main(){int list[Nelements];LeerArreglo(list);ReversarArreglo(list);ImprimirArreglo(list);}Aqu se pasa la lista vaca, y debe regresar llena de los datos ingresados por tecladoLa lista ingresada se enva a la funcin y debe regresar reversadaLa lista ser impresa

  • Generalizando el Nmero de ElementosEl problema plantea que se debe ingresar una cantidad indefinida de nmeros.Para declarar un arreglo, debemos decidir previamente cuantos elementos este va a tener.La estrategia es asumir un mximo, mucho mayor de lo que se va a necesitar.Quizs no use todos los elementos, pero declara un mximo por si acaso.Debemos conocer cuantos elementos vamos usando hasta el momento.Esta informacin se almacena en una variable separada nEl tamao del arreglo se conoce como el tamao mximo.El nmero de elementos usados hasta el momento es el tamao efectivo.

  • Revisando las FuncionesSi asumimos que al enviar un arreglo a una funcin, esta lo modifica y lo regresa modificado:La funcin que lea los datos del arreglo Necesita:El arregloEl mximo numero de elementosLa centinela para detener la lecturaDevuelveEl tamao efectivo del arregloLas funciones que reversan e imprimen el arreglo NecesitanEl arregloEl tamao efectivoRetornanNada (void) Entonces son procedimientos

  • Los PrototiposA una funcin que usa un arreglo entonces, siempre se le manda:El arreglo y El tamao, ya sea el mximo o el efectivoLos prototipos seran:int LeeArreglo(int arreglo[],int max, int centinela);void ReversaArreglo(int arreglo[],int n);void ImprimeArreglo(int arreglo[],int n);Cuando una funcin recibe un arreglo como parmetro, se indica:El tipo del arreglo, el nombre en la funcin, seguido de [ ] vacos, NINGUN VALOR DENTRO DE ELLOS!!!

  • Funcionamiento InternoCuando una variable se enva a una funcin, lo que realmente se enva es una copia de la variable.Si en la funcin, se modifica el valor de dicho parmetro, al retornar, no quedar rastro de dichos cambios.El programa que llame a la funcin, no se enterar de los cambios, pues esta fue llamada por valor.Al pasar un arreglo, sin embargo, no se enva una copia de cada elemento del arreglo.Se enva la direccin de memoria del primer elemento del arreglo.Cualquier cambio que se desee hacer sobre el arreglo, se hace efectivamente sobre el arreglo que fue originalmente enviado a la funcin.Al regresar al programa que llamo a la funcin, el arreglo aparece modificado.

  • El Programa Principal#define MAX 250#define CENTINELA 0static int LeerArreglo(int lista[],int max,int centinela);static void ReversarArreglo(int lista[],int n);static void ImprimirArreglo(int lista[],int n);main(){int lista[MAX],n;n = LeerArreglo(lista, MAX,CENTINELA);ReversarArreglo(lista,n);ImprimirArreglo(lista,n);}Leer arreglo devuelve el tamao efectivo del arregloLa misma lista que se manda, va a ser modificada por ReversarArreglo. Note que es un procedimiento.

  • La Estrategia para ReversarPara reversar los elementos almacenados en cualquier arreglo. Ejemplo:1120341558192Se puede dividir el arreglo en dos partesSe intercambian los elementos de la primera mitad, con los de la segundaQuiere decir que si el arreglo es de tamao n, se deben hacer n/2 intercambiosY recuerde, mientras avanza en la primera mitad, retrocede en la segundaEl primero se intercambia con el ultimo, el segundo con el penltimo, etc

  • La Implementacinstatic int LeerArreglo(int lista[],int max,int centinela){int i,valor;for(i = 0; i < max;i++){valor = GetInteger();if(valor == centinela) break;lista[i] = valor;}return(i);}static void ReversarArreglo(int lista[],int n){int i,tmp;for(i = 0; i
  • En lugar de almacenar valores en los elementos de un arreglo, algunas aplicaciones usan los arreglos para almacenar ndices, que permiten llevar estadsticas, de un dato en particular.Por ejemplo:Se pidi a 40 estudiantes que calificaran la calidad de la comida de la cafetera en una escala del 1 al 10 (1 es terrible y 10 excelente). Escriba un programa en C que pida las 40 respuestas y luego muestre un resumen del resultado.Arreglos Para Tabular

  • SolucinEn este tipo de problemas se deben usar dos arreglos:El primero es el que almacena las respuestas, los datos a los que se les va a calcular estadsticas(40 respuestas).El segundo es que almacena las estadsticas, en este caso, la frecuencia con la que se dio cada respuesta(10 tipos de respuestas).Los pasos para resolverlos son:Permitir el ingreso de las 40 respuestas.Contabilizar cada respuesta. Cada respuesta incrementa el contador respectivo, el cual sera un elemento del arreglo de frecuencias.Mostrar la tabla con el resumen de respuestas.

  • El Enfoque AdecuadoSe necesitan dos arreglos:Frecuencias es un conjunto de contadores:Frecuencias[0] es el contador para la respuesta 1Frecuencias[5] es el contador para la respuesta 4Por cada elemento de respuestas se aumenta 1 al elemento de frecuencias correspondiente

  • El Programa Principal#define MAX_RESP 40#define MAX_FREC 10#define CENTINELA 0static void InicializarArreglo(int arreglo[],int max);static int LeerArreglo(int arreglo[],int max, int sent);static void Contabilizar(int resp[],int n, int freq[]);static void ImprimirArreglo(int arreglo[],int n);

    main(){int Respuestas[MAX_RESP], frecuencias[MAX_FREC],n;InicializarArrelo(frecuencias, MAX_FREC);n = LeerArrelo(Respuestas, MAX_RESP, CENTINELA);Contabilizar (Respuestas,n,frecuencias);ImprimirArreglo(frecuencias, MAX_FREC);}Frecuencias es un conjunto de contadores, hay que inicializarlos a 0 antes de usarlosLee hasta 40 respuestas. Cada respuesta solo puede ser un valor entre 1 y 10Contabiliza y coloca el resultado en el arreglo frecuencias

  • La Implementacin

    static InicializarArreglo(int arreglo[],int max){int i;for(i =0; i < max; i++){arreglo[i] = 0;}}static int LeerArreglo(int arreglo, int max, int centi){int i;for(i = 0; i < max; i++){while(TRUE){valor = GetInteger();if(valor == centi) return(i);if(valor >=1 && valor

  • Un arreglo en C tambin se puede inicializar de las siguientes formas:Crear un arreglo de 3 elementosInicializando cada elemento:int A[]={11,2,8}; int A[3]={11,2,8};Inicializando todos los elementos con el mismo valor:int A[3]={0};

    Inicializacin de un Arreglo

  • Cmo calcular el tamao de un arreglo?Si inicializamos una arreglo sin indicar su ancho, Como podemos saber el ancho, para futuros usos en el programa?Sabemos que sizeof devuelve el nmero total de bytes que ocupa un tipo de dato o una variable de un tipo dado.sizeof(Arreglo) devolver el total de bytes que ocupan todos los elementos de un arreglo.sizeof(Arreglo[0]) devuelve el tamao total de bytes que ocupa un elemento del arreglo.sizeof(Arreglo)/sizeof(Arreglo[0]) devolver el numero del elementos de Arreglo.sizeof(Arreglo) devuelve 32sizeof(Arreglo[0]) devuelve el desfase: 8sizeof(Arreglo)/sizeof(Arreglo[0]) devuelve 4, justo el nmero de elementos del arreglo.

  • En C, los elementos de un arreglo pueden ser de cualquier tipoEsto quiere decir que los elementos de un arreglo pueden ser a su vez, arreglos.Arreglos de arreglos, se conocen como arreglos multidimensionales. El mas comn de estos, es el de dos dimensiones, conocido tambin como Matriz.Un ejemplo de una matriz, es un tablero de tres en rayaEste es un arreglo de 3 elementos, donde cada elemento es un arreglo, de tres elementos tambin.Arreglos Multidimensionalesint A[3][3];

    (0,0)

    (0,1)

    (0,2)

    (1,0)

    (1,1)

    (1,2)

    (2,0)

    (2,1)

    (2,2)

  • Paso de Arreglos MultidimensionalesLos arreglos multidimensionales tambin pueden ser pasados entre funcionesPara mostrar un tablero de tres en raya se podra usar un arreglo de caracteres de 3 por 3:char tablero[3][3];Para mostrar el tablero podramos usar una funcin, que seria declaradaMostrarTablero(char tablero[3][3]); oMostrarTablero(char tablero[][3]);La cabecera de la implementacin luce exactamente igual

    void MostrarTablero(char tablero[][3]){int fila, columna;for(fila = 0; fila < 3; fila++){ if(fila != 0) printf(----+---+---\n); for(columna = 0; columna < 3; columna++) { if(columna != 0) printf(|; printf( %c , board[fila][columna]); } printf(\n);}}X | O | X---+---+--- | X | O---+---+---X | | O

  • InicializacinUn arreglo multidimensional tambin se puede inicializarstatic double MatrizIdentidad[3][3] = {{1,0,0},{0,1,0}{0,0,1}};As podemos inicializar todos los elementos de una matriz desde el inicio, sin necesidad de usar lazos anidados.

  • Bsqueda en un ArregloSe refiere al proceso para encontrar un elemento particular en un arreglo.Una de las estrategias mas comunes y simples para buscar un dato en un arreglo es:Revisar uno por uno los elementos del mismo, este mtodo se conoce como bsqueda lineal.Escribir una funcin que determine si un valor dado se encuentra en un arreglo de elementos enteros, y si es as, indique su posicin-

  • SolucinDato a buscar: 58

    int EncontrarElemento(int valor, int arreglo[ ] ,int n){for(i=0; i

  • Bsqueda BinariaLa bsqueda lineal es conocida por no ser tan eficiente.Si buscamos un dato que justo esta en el ultimo elemento del arreglo, tendremos que revisar todo el arreglo para llegar a elOtro mecanismo de bsqueda es la bsqueda binaria:Para este tipo de bsqueda se asume que el arreglo contiene valores ordenados.Si asumimos que el valor que buscamos esta entre los elementos 0 y n-1, en vez de probar con cada elemento, probamos solo con el de la mitad (0+n-1)/2Si el valor buscado es menor que el elemento de la mitad, ya no buscamos de 0 a n-1, si no de 0 a la mitad.Si el valor buscado es mayor que el elemento de la mitad, ya no buscamos de 0 a n-1, si no de la mitad hasta n-1.Si el valor buscado es igual al elemento de la mitad, terminamos la bsquedaCon estos nuevos lmites, repetimos la busqueda hasta que el limite inferior sea mayor que el limite superior, en cuyo caso sabremos que el valor buscado no esta en el arreglo.mitadmitadmitadSi buscamos la cadena MantaPalabra encontrada en la posicin 5

  • Ejercicio En ClaseEscribir una funcin EncontrarCadena que busque una cadena en un arreglo de las mismas

    int EncontrarCadena(string valor, string conjunto[ ], int n){int desde, hasta, mid, cmp;desde = 0;hasta = n-1;while(desde mitad)Se determina que el valor esta en la parte inferior a la mitad(mitad->hasta)

  • OrdenamientoSe refiere al proceso de arreglar los elementos en una arreglo, para que almacenen los datos en un orden definido. Ejemplo: las compaas telefnicas ordenan sus listas de cuentas por apellido y luego por nombreUn mtodo sencillo es el de la seleccin. Se llama as porque los valores mas pequeos se van seleccionando.El mtodo consiste en revisar cada elemento del arreglo, desde le primero hasta el penltimoDesde la posicin en la que nos encontremos revisando, hasta el final del arreglo, buscamos el menor de los nmerosUna vez encontrado, lo intercambiamos con el elemento que estamos revisandoAl terminar la revisin de todos los elementos tendremos un arreglo ordenadoEl menor es 26El menor es 31El menor es 41El menor es 53====ARREGLO ORDENADOfor(i = 0; i
  • Implementacin

    static void Ordenar(int arreglo[ ],int n){int desde, posmenor,tmp;for(desde = 0; desde