21 - Arreglos: conceptos

Hemos empleado variables de distinto tipo para el almacenamiento de datos (variables Int, Float, Double, Byte, Short, Long, Char, Boolean) En esta sección veremos otros tipos de variables que permiten almacenar un conjunto de datos en una única variable.

Un arreglo es una estructura de datos que permite almacenar un CONJUNTO de datos del MISMO tipo.
Con un único nombre se define un arreglo y por medio de un subíndice hacemos referencia a cada elemento del mismo (componente)

Problema 1

Se desea guardar los sueldos de 5 operarios.
Según lo conocido deberíamos definir 5 variables si queremos tener en un cierto momento los 5 sueldos almacenados en memoria.
Empleando un arreglo solo se requiere definir un único nombre y accedemos a cada elemento por medio del subíndice.

arreglos en Kotlin

Proyecto98 - Principal.kt

fun main(parametro: Array<String>) {
    val sueldos: IntArray
    sueldos = IntArray(5)
    //carga de sus elementos por teclado
    for(i in 0..4) {
        print("Ingrese sueldo:")
        sueldos[i] = readln().toInt()
    }
    //impresion de sus elementos
    for(i in 0..4) {
        println(sueldos[i])
    }
}

Para declarar un arreglo de enteros definimos una variable de tipo IntArray:

    val sueldos: IntArray

Para crearlo al arreglo y que se reserve espacio para 5 componentes debemos hacer:

    sueldos = IntArray(5)

Para acceder a cada componente del arreglo utilizamos los corchetes y mediante un subíndice indicamos que componente estamos procesando:

    for(i in 0..4) {
        print("Ingrese sueldo:")
        sueldos[i] = readln().toInt()
    }

Cuando i valore 0 estamos cargando la primer componente del arreglo.

Las componentes comienzan a numerarse a partir de cero y llegan hasta el tamaño que le indicamos menos 1.

Una vez que cargamos todas sus componentes podemos imprimirlas una a una dentro de otro for:

    for(i in 0..4) {
        println(sueldos[i])
    }

Si queremos conocer el tamaño de un arreglo luego de haberse creado podemos acceder a la propiedad size:

    val sueldos: IntArray
    sueldos = IntArray(5)
    println(sueldos.size) // se imprime un 5

Es más común crear un arreglo de enteros en una sola línea con la sintaxis:

    val sueldos = IntArray(5)

Acotaciones

La biblioteca estándar de Kotlin contiene todas las clases básicas que se requieren para programar con este lenguaje organizado en paquetes.

En el paquete kotlin podemos identificar que se encuentra declarada la clase IntArray.

Las otras clases de arreglos que suministra Kotlin son:

ByteArray
ShortArray
LongArray
FloatArray
DoubleArray
BooleanArray
CharArray

No hay uno para manejar String, en los próximos conceptos veremos como trabajar con este tipo de dato.

Problema 2

Definir un arreglo de 5 componentes de tipo Float que representen las alturas de 5 personas.
Obtener el promedio de las mismas. Contar cuántas personas son más altas que el promedio y cuántas más bajas.

Proyecto99 - Principal.kt

fun main(parametro: Array<String>) {
    val alturas = FloatArray(5)
    var suma = 0f
    for(i in 0..alturas.size-1){
        print("Ingrese la altura:")
        alturas[i] = readln().toFloat()
        suma += alturas[i]
    }
    val promedio = suma / alturas.size
    println("Altura promedio: $promedio")
    var altos = 0
    var bajos = 0
    for(i in 0..alturas.size-1)
        if (alturas[i] > promedio)
            altos++
        else
            bajos++
    println("Cantidad de personas más altas que el promedio: $altos")
    println("Cantidad de personas más bajas que el promedio: $bajos")
}

Creamos un arreglo con datos de tipo flotante de 5 elementos utilizando la clase FloatArray:

    val alturas = FloatArray(5)

En el primer for cargamos cada altura y la acumulamos en la variable suma. La variable suma se define por inferencia de tipo Float si le agregamos el caracter "f" o "F":

    var suma = 0f

Dentro del for cargamos y acumulamos:

    for(i in 0..alturas.size-1){
        print("Ingrese la altura:")
        alturas[i] = readln().toFloat()
        suma += alturas[i]
    }

Luego cuando salimos del for obtenemos la altura promedio de las personas y la mostramos:

    val promedio = suma / alturas.size
    println("Altura promedio: $promedio")

Para contar la cantidad de personas más altas que el promedio y más bajas debemos definir dos contadores y dentro de otro for controlar cada altura con respecto al promedio:

    var altos = 0
    var bajos = 0
    for(i in 0..alturas.size-1)
        if (alturas[i] > promedio)
            altos++
        else
            bajos++

Como el for tiene una sola sentencia no son obligatorias las llaves.

Fuera del for mostramos los dos contadores:

    println("Cantidad de personas más altas que el promedio: $altos")
    println("Cantidad de personas más bajas que el promedio: $bajos")

Problema 3

Cargar un arreglo de 10 elementos de tipo entero y verificar posteriormente si el mismo está ordenado de menor a mayor.

Proyecto100 - Principal.kt

fun main(parametro: Array<String>) {
    val arreglo = IntArray(10)
    for(i in 0..arreglo.size-1) {
        print("Ingrese elemento:")
        arreglo[i] = readln().toInt()
    }
    var ordenado = true
    for(i in 0..arreglo.size-2)
        if (arreglo[i+1] < arreglo[i])
            ordenado = false
    if (ordenado)
        print("Los elementos están ordenados de menor a mayor")
    else
        print("Los elementos no están ordenados de menor a mayor")
}

Definimos un arreglo de 10 elementos de tipo entero y procedemos a cargarlo por teclado:

    val arreglo = IntArray(10)
    for(i in 0..arreglo.size-1) {
        print("Ingrese elemento:")
        arreglo[i] = readln().toInt()
    }

Definimos una variable de tipo Boolean con el valor true (suponiendo que el arreglo está ordenado de menor a mayor antes de analizarlo.

    var ordenado = true

Por inferencia sabe el compilador que la variable ordenado debe ser de tipo Boolean, la otra forma de definir es:

    var ordenado: Boolean = true

Ahora mediante otro for procedemos a comparar un elemento de la posición i+1 con el de la posición i, si se cumple que sea mayor podemos ya inferir que el arreglo no está ordenado:

    for(i in 0..arreglo.size-2)
        if (arreglo[i+1] < arreglo[i])
            ordenado = false

Fuera del for preguntamos por el contenido de la variable "ordenado" si tiene almacenado el valor true significa que el vector está ordenado de menor a mayor:

    if (ordenado)
        print("Los elementos están ordenados de menor a mayor")
    else
        print("Los elementos no están ordenados de menor a mayor")

Si queremos hacer un poco más eficiente la verificación de si el array está ordenado podemos cortar las comparaciones en cuanto aparezca un elemento no ordenado mediante la palabra clave break:

    for(i in 0..arreglo.size-2)
        if (arreglo[i+1] < arreglo[i]){
            ordenado = false
            break
        }

El comando break sale de la estructura repetitiva que lo contiene en forma inmediata sin continuar el ciclo.

Propiedad indices de la clases IntArray, ByteArray, LongArray etc.

La clase IntArray tiene una propiedad IntRange llamada indices que almacena el rango mínimo y máximo del arreglo.
La propiedad indices podemos utilizarla en el for para recorrer las componentes:

Problema 4

Cargar un arreglo de 10 elementos de tipo entero. Imprimir luego el primer y último elemento.

Proyecto101 - Principal.kt

fun main(parametro: Array<String>) {
    val arreglo = IntArray(10)
    for(i in arreglo.indices) {
        print("Ingrese elemento:")
        arreglo[i] = readln().toInt()
    }
    println("Primera componente del arreglo ${arreglo[0]}")
    println("Ultima componente del arreglo ${arreglo[arreglo.lastIndex]}")
}

Es más conveniente utilizar la propiedad indices en lugar de disponer el rango: 0..arreglo.size-1 si vamos a recorrer todo el arreglo.

Para acceder a la última componente del arreglo utilizamos la propiedad lastIndex que devuelve el último índice válido:

    println("Ultima componente del arreglo ${arreglo[arreglo.lastIndex]}")

Iterar con un for un objeto array

Además de la forma que hemos visto para acceder a los elementos de un arreglo mediante un subíndice podemos utilizar la estructura repetitiva for con iteradores.

Problema 5

Cargar un arreglo de 5 elementos de tipo entero. Imprimir luego todo el arreglo.

Proyecto102 - Principal.kt

fun main(parametro: Array<String>) {
    val arreglo = IntArray(10)
    for(i in arreglo.indices) {
        print("Ingrese elemento:")
        arreglo[i] = readln().toInt()
    }
    for(elemento in arreglo)
        println(elemento)
}

Para iterar un arreglo completo de un array con un for utilizamos la siguiente sintaxis:

    for(elemento in arreglo)
        println(elemento)

Cada vuelta del for se almacena en la variable elemento un valor almacenado en la variable "arreglo".

Como vemos es una sintaxis muy simple para recorrer un arreglo y acceder a cada elementos para consultarlo.

Otras características de los arreglos que pueden ser útiles.

Imprimir cada elemento y su índice iterando el arreglo llamando al método withIndex de la clase IntArray:

    for((indice, elemento) in arreglo.withIndex())
        println("En el índice $indice se almacena el elemento $elemento")

Carga de los elementos utilizando el for como iterador;

    for((indice, elemento) in arreglo.withIndex())
    {
        print("Ingrese elemento:")
        arreglo[indice] = readln().toInt()
    }

Clase Array

Kotlin tiene una clase genérica llamada Array que permite almacenar valores de cualquier tipo primitivo y veremos más adelante de tipo objeto.

Veamos como crear un arreglo con tipos de dato Double:

fun main(parametro: Array<String>) {
    val sueldos=arrayOf<Double>(1200.0, 1700.50, 6000.0 )
    for(i in 0..sueldos.size-1)
        print("${sueldos[i]} - ")
}

Mediante la función arrayOf indicamos los elementos a almacenar en el arrego.

Podemos utilizar la función arrayOfNulls y pasar como parámetro la cantidad de espacio a reservar:

fun main(parametro: Array<String>) {
    val alturas = arrayOfNulls<Float>(3)
    alturas[0]=1.72f
    alturas[1]=1.79f
    alturas[2]=1.67f
    for(indice in 0..alturas.size-1)
        print("${alturas[indice]} -")
}

Podemos ahora entender el parámetro que llega a la función main de todo programa de Kotlin:

fun main(parametro: Array<String>) {

Se trata de un arreglo de tipo String.

Probemos de ejecutar el siguiente programa:

fun main(parametro: Array<String>) {
    for(indice in 0..parametro.size-1)
        print("${parametro[indice]} -")
}

Primero debemos configurar parámetros del programa (son datos que podemos pasar cuando ejecutamos nuestro programa desde la línea de comandos del sistema operativo), estando dentro del entorno de IntelliJ IDEA accedemos a la opción Run ->Edit Configuration...:

Array<String> Kotlin

Ahora cuando ejecutamos el programa el vector 'parametro' almacena tres elementos de tipo String con las cadenas que cargamos 'uno dos tres':

Array<String> Kotlin

Podemos iterar todos los elementos del Array mediante un for, como lo vimos con los otros tipos de arreglo:

fun main(parametro: Array<String>) {
    for(elemento in parametro)
        print("$elemento -")
}

Problemas propuestos

  • Desarrollar un programa que permita ingresar un arreglo de 8 elementos enteros, e informe:
    El valor acumulado de todos los elementos.
    El valor acumulado de los elementos que sean mayores a 36.
    Cantidad de valores mayores a 50.
    (Definir dos for, en el primero realizar la carga y en el segundo proceder a analizar cada elemento)
  • Realizar un programa que pida la carga de dos arreglos numéricos enteros de 4 elementos. Obtener la suma de los dos arreglos elemento a elemento, dicho resultado guardarlo en un tercer arreglo del mismo tamaño.
Solución
Proyecto103

fun main(parametro: Array<String>) {
    val arreglo = IntArray(8)
    for(i in arreglo.indices) {
        print("Ingrese elemento:")
        arreglo[i] = readln().toInt()
    }
    var suma = 0
    var sumaMayor36 = 0
    var cantMayor50 = 0
    for(elemento in arreglo) {
        suma += elemento
        if (elemento > 30)
            sumaMayor36 += elemento
        if (elemento > 50)
            cantMayor50++
    }
    println("Valor acumulado del arreglo: $suma")
    println("Valor acumulado de los elementos mayores a 36: $sumaMayor36")
    println("Cantidad de elementos mayores a 50: $cantMayor50")
}




Proyecto104

fun main(parametro: Array<String>) {
    val arreglo1 = IntArray(4)
    val arreglo2 = IntArray(4)
    println("Carga del primer arreglo")
    for(i in arreglo1.indices) {
        print("Ingrese elemento:")
        arreglo1[i] = readln().toInt()
    }
    println("Carga del segundo arreglo")
    for(i in arreglo2.indices) {
        print("Ingrese elemento:")
        arreglo2[i] = readln().toInt()
    }
    val arregloSuma = IntArray(4)
    for(i in arregloSuma.indices)
        arregloSuma[i] = arreglo1[i] + arreglo2[i]
    println("Arreglo resultante")
    for(elemento in arregloSuma)
        println(elemento)
}