Algoritmos y Estructura de Datos


Save this PDF as:
 WORD  PNG  TXT  JPG

Tamaño: px
Comenzar la demostración a partir de la página:

Download "Algoritmos y Estructura de Datos"

Transcripción

1 Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz 18/10/2018 Material introductorio lenguaje Go Cátedra a cargo del Dr. O. Bruno

2 Que es GO? Go es un lenguaje de programación inspirado en C, compilado, estáticamente tipado, concurrente. Podemos decir que nació en el año 2009 y está siendo utilizado por empresas como Docker, UBER, entre otros. Los diseñadores de este lenguaje son: Rob Pike y Ken Tompson. Go fue construido para ser utilizado como un lenguaje orientado a software de sistemas (es decir, sistemas operativos, drivers de dispositivos), lo cual animó a desarrolladores de C y C++. Según el equipo de Go, los desarrolladores de aplicaciones, y no los desarrolladores de software de sistemas, se han convertido en los principales usuarios de Go. no existen dependencias a la hora de ejecutar programas compilados con Go. No hay que preocuparse sobre si los usuarios tienen Ruby o la JVM instalada o, si la tienen, qué versión tendrán. Por este motivo Go se está convirtiendo en un lenguaje popular con el que desarrollar aplicaciones de línea de comandos u otro tipo de programas de utilidades que necesiten ser distribuibles. Algunas de sus principales características Compilado: La compilación es el proceso de traducir el código fuente que escribas en un lenguaje de más bajo nivel puede ser ensamblador (como en el caso de Go) u otro tipo de lenguaje intermedio (como en el caso de Java o C#)Los lenguajes compilados suelen ser más rápidos y los ejecutables pueden funcionar sin depedencias adicionales (al menos esto es cierto para lenguajes como C, C++ y Go, los cuales compilan directamente en ensamblador) Estáticamente Tipado: Estar tipado estáticamente implica que las variables deben ser de un tipo específico (int, string, bool, []byte, etc). Esto se consigue indicando el tipo a la hora de definir la variable o, en muchos casos, dejando al compilador que infiera el tipo Concurrente: Está inspirado en CSP (Communicating sequential processes de Charles Antony Hoare, ganador del premio Turing en 1980). Uso poco usual de POO: Go no usa clases, no usa herencia y el uso de interfaces se realiza de manera implícita. Esto con el fin de mejorar el rendimiento al momento de diseñar tu software. Uso de paquetes: Se usan los paquetes para organizar el código. Un paquete puede tener varios archivos.go que permiten definir lo que va a realizar el paquete. Para usar un paquete en tu programa, debes importarlo. Recolección de Basura: Los lenguajes con recolectores de basura (e.j., Ruby, Python, Java, JavaScript, C#, Go) son capaces de realizar un seguimiento de las variables y liberarlas cuando no se utilicen más. La recolección de basura añade overhead, pero también elimina bugs devastadores La sintaxis de C suele implicar que las líneas deban terminar en punto y coma y que debe haber paréntesis que delimitan condicionales. Go acaba con estas prácticas, aunque los paréntesis se siguen usando para controlar la precedencia de operadores. Ejecutar Código Go en línea 1

3 En Go, el punto de entrada de un programa es una función llamada main ubicada en el paquete main. Imports Go incluye ciertas funciones predefinidas, como println, las cuales pueden ser utilizadas sin referenciar. No podemos ir muy lejos sin utilizar la librería estándar de Go y, eventualmente, sin usar librerías de terceros. En Go, la palabra clave import se utiliza para declarar qué paquetes van a ser utilizados por el código del fichero en el que estemos trabajando. Go es estricto en lo que respecta a la importación de paquetes, tanto que tu código no compilará si importas un paquete que no utilizas. la librería estándar de Go está bien documentada, ejemplo paquete fmt Tipos de datos Los datos lógicos pueden almacenarse en variables de tipo bool. Los valores que pueden tener son true y false (en minúsculas). El valor cero (el valor por defecto) de las variables de tipo bool es false. Las operaciones que se pueden realizar en Go con elementos lógicos son las siguientes: Los números 2

4 Cabe desatacar que no hay un tipo float. String Las vemos mas abajo Operaciones Comparaciones en Go es imprescindible indicar explícitamente cualquier conversión. En Go las conversiones no devuelven errores en tiempo de ejecución. Si un valor no encaja en otro tipo, se hace una simplificación. Por ejemplo, al pasar de un float32 a int se elimina la parte decimal. Las conversiones se pueden utilizar para la conversión de tipos no numéricos. La sintaxis es siempre la misma: <tipo-nuevo>(variable). Variables y Declaraciones Go asigna un valor por defecto a las variables. A los enteros se les asigna 0, a los booleanos false, a los strings "" var mivariable int mivariable = con inferencia de tipos Mivariable:=9000 3

5 Es importante que recuerdes que := se utiliza para declarar la variable a la vez que se le asigna valor. Por qué? Porque una variable no puede ser definida dos veces (al menos no en el mismo ámbito). como ocurre con los imports, Go no te va a permitir tener variables sin utilizar. recuerda que puedes usar var NOMBRE TIPO cuando declaras una variable y le asignas su valor por defecto, NOMBRE := VALOR cuando declaras y asignas valor a una variable, y NOMBRE = VALOR cuando asignas valor a una variable previamente declarada. Estructuras de control IF La condición se escribe sin paréntesis. No sólo son opcionales, sino que la utilidad de formateo de código Go los elimina de forma rutinaria. Al utilizar IF es imprescindible utilizar las llaves. No tenemos la opción de no ponerlas y ejecutar sólo la siguiente instrucción. La condición IF puede ir acompañada de una una sección ELSE. FOR El uso de paréntesis en el FOR es opcional. También al igual que en el caso del IF, el formateador de código elimina los paréntesis por ser innecesarios. For o while?? func main() { contador := 0 for contador < 10 { contador = contador + 1 fmt.println("hemos contado hasta", contador) En el caso de Go, el WHILE sólo se trata de un caso particular de FOR; no se necesita otra palabra reservada. Si añadimos una operación de inicialización y una de incremento func main() { var contador int for contador = 0; contador < 10; contador = contador + 1 { //Ahora el bucle está vacío fmt.println("hemos contado hasta", contador) Ambas opcionales, exactamente igual que en C/C++. DO.WHILE..no existe.. (la sonrisa pertenece a la profe) Range 4

6 La palabra clave de rango se usa en bucles para iterar datos en estructuras de datos (matrices, segmentos, cadenas, mapas, etc.). 1. Con matrices y segmentos, el rango proporciona índices y valores. 2. Con los mapas, el rango proporciona pares clave-valor. 3. Con la cadena, el rango proporciona el índice de cada carácter Unicode en la cadena y sus caracteres Unicode correspondientes. 4. Si los valores de índice no son necesarios, se pueden descartar utilizando _. func main() { numeros := []int{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 sum := 0 for indice, valor := range numeros{ sum += valor fmt.print("[", indice, valor, "] ") fmt.println("\nsum es :: ", sum) str := "Hello, World!" for indice, c := range str { fmt.print("[", indice, ",", string(c), "] ") Estructuras Una estructura es una agrupación ordenada de distintos elementos de información. Cada uno de ellos con su propio tipo de datos correspondiente. import "fmt" type fichaalumno struct { nombre string //Nombre del alumno humano bool //True si el alumno es humano color int //Color del sable de luz en entero func main() { var gopadawan fichaalumno gopadawan.nombre = "GoPadawan" gopadawan.humano = true gopadawan.color = fmt.println("información de GoPadawan:", gopadawan) Declaración de Funciones pueden devolver más de un valor func log(message string) { func add(a int, b int) int { func power(name string) (int, bool) { 5

7 Se puede usar una sintaxis abreviada si los parámetros son del mismo tipo: func add(a, b int) int { Funciones Variádicas Pueden ser llamadas con cualquier número de argumentos func sum(nums...int){ sum(1, 2) sum(1, 2, 3) Array En Go los arrays están implementados dentro del lenguaje. No son objetos, ni abstracciones externas. Forman parte intrínseca del lenguaje y su uso es muy intuitivo. Cuando definimos un array especificamos un tipo de elemento y el número de elementos. Ambos son inmutables y definen el tipo del array. Un array de 4 enteros es de un tipo distinto de un array de 5 enteros. Definiendo arrays Vamos a definir unos cuantos arrays. Un array sin valores. Mejor dicho: un array cuyos elementos adquieren el valor cero. var enteros [2]int Un array con dos elementos definidos. var eb [2]string = [2]string{"Epi", "Blas" Definición corta del caso anterior. var eb = [2]string{"Epi", "Blas" Definición aún más corta. eb := [2]string{"Epi", "Blas" Definición sin especificar (explícitamente) el tamaño del array. eb := [...]string{"epi", "Blas" 6

8 Como en el resto de casos, a menos que especifiquemos el valor de los elementos del array, se inicializan con el valor cero. Los arrays en memoria Las variables que contienen un array ocupan en memoria el tamaño de cada elemento multiplicado por el número de elementos. Nada más. Habiendo visto cómo es un array, veamos cómo NO es un array: Un array no es un puntero o una referencia Slices Un slice es una estructura ligera que encapsula y representa una porción de un array. Hay varias formas de crear un slice. puntaje := []int{1,4,293,4,9 crea e inicializa una estructura de enteros 5 posiciones. Otro modo es usar la función make que está sobrecargada y tiene varios objetivos. Para declarar: puntaje := make([]int, 10) Crea un slice de longitud 10 y capacidad 10. Esto significa que sería válido asignar valores a scores[0].. scores[1] scores[9].. recordemos que las estructuras enteras en Go se inicializan en 0. Longitud es el tamaño del slice y la capacidad es el tamaño del array subyacente Ejemplo: Si quisiéramos configurar por separado longitud y capacidad puntaje := make([]int, 0, 10) Tendríamos un slice de longitud 0 y capacidad 10. 7

9 PRUEBEN!! Cual piensan que es la diferencia?? Que podemos y que no podemos hacer?? Si tiene longitud 0, como podemos utilizarlo entonces?? Necesitamos ampliar la longitud explícitamente o utilizar alguna función que lo haga. Modificar la longitud puntaje = puntaje[0:5] Esto amplía la longitud en 5, eso nos permite poner datos en las posiciones 0 a 4. El límite de la expansión explícita es la capacidad que hayamos dado. Expandir con append: Nos permite ir ocupando los espacios desde la posición 0 en forma secuencial. puntaje = append(puntaje, 5) Almacena en la posición 0 el valor 5 Si tengo mi slice con datos en las 10 posiciones según la declaración/inicialización puntaje := make([]int, 0, 10) y agrego un dato mas con append expandiendo el slice, cual sería la longitud?? Y la capacidad?? Utilicen la función len para la longitud y cap para ver la capacidad. Son iguales?? Encuentran un patrón?? Los slice tienen internamente una estructura de tipo cabecera y elementos, los elementos en las funciones pasan por referencia, pero no así la cabecera, La siguiente imagen muestra cómo se almacenan en memoria los slices: 8

10 Como se indica en la imagen, tenemos un puntero ptr que es un puntero (referencia) al array, una longitud len que contiene un entero (positivo) con la longitud en uso, y una capacidad cap con la capacidad máxima de este slice. La siguiente imagen muestra un caso concreto: un trozo asociado a un array de 5 posiciones. En este caso, el tamaño y la capacidad tienen el mismo valor, lo que significa que el trozo está al máximo de su capacidad. Veamos ahora un caso den el que el trozo desecha las primeras y últimas posiciones del array. Entonces como lo expandimos?? Podemos usar el make para declarar un nuevo slice mas grande y copiar los datos usando la función copy(destino,origen). Go tiene una función que hace esto append, puntos = append(puntos, 4) agrega el 4 al slice puntos = append(puntos, puntos2...) concatena el slice2 al slice original puntos2 := append([]int(nil), puntos...) hace una copia String Las cadenas están compuestas de letras y números y pueden ser definidas usando comillas dobles, son solo slices de bytes de solo lectura con un poco de soporte sintáctico adicional del lenguaje. barra: = "/ usr / ken" [0] // produce el valor de byte '/'. 9

11 usr: = "/ usr / ken" [0: 4] // produce la subcadena "/ usr" str: = string (barra) // muestra el carácter Punteros variables por referencia Go soporta apuntadores, lo cual nos permite pasar referencias de valores y datos entre las funciones de nuestro programa. El código *iptr en el cuerpo de la función dereferencía el apuntador de su dirección de memoria a el valor actual de esa dirección. Si asignamos un valor a un apuntador dereferenciado se cambia el valor que se está almacenando en dicha dirección de memoria. La sintaxis &i devuelve la dirección en memoria de i, i.e. un apuntador a i. EJ: func zeroptr(iptr *int) { *iptr = 0 func main() { i := 1 zeroptr(&i) fmt.println("zeroptr:", i) /// zeroptr: 0 Métodos Los métodos están asociados con Estructuras. type Persona struct { nombre string apellido string edad int func (p *Persona) incrementaedad() int { p.edad++ return p.edad func main() { me:= Persona{"Bill", "Broughton", 29, "Brown", true fmt.println(me.incrementaedad()) // Output: 30 fmt.println(me.edad) // Output: 30 10

12 En la práctica Búsqueda binaria func BusquedaBinaria(data []int, value int) bool { size := len(data) Primero := 0 Ultimo := size - 1 medio := 0 for Primero <= Ultimo { medio = Primero + (Ultimo - Primero)/2 if data[medio] == value { return true else if data[medio] < value { Primero = medio + 1 else { Ultimo = medio - 1 return false 11

SitemapDe diefstal van mijn jeugd | 3D单机游戏 | الوشم والجسم الفن