Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en...

12
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

Transcript of Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en...

Page 1: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

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

Page 2: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

1

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.

https://github.com/golang/go/wiki/GoUsers.

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.

https://golang.org/

Ejecutar Código Go en línea

Page 3: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

2

https://play.golang.org/

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

https://golang.org/pkg/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

Page 4: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

3

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 = 9000

0 con inferencia de tipos

Mivariable:=9000

Page 5: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

4

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

Page 6: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

5

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 = 65280

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) {}

Page 7: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

6

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"}

Page 8: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

7

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.

Page 9: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

8

Cual piensan que es la diferencia?? Que podemos y que no podemos hacer??

PRUEBEN!!

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:

Page 10: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

9

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 '/'.

Page 11: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

10

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

}

Page 12: Algoritmos y Estructura de Datos · Algoritmos y Estructura de Datos Departamento de Ingeniería en Sistemas de Información Universidad Tecnológica Nacional FRBA Ing.Roxana Leituz

11

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

}