Bienvenidos a este nuevo capítulo de este Curso Gratis de Programación #15 Arrays

Tabla de contenidos

¿Te gustaría enterarte de cuando lanzamos descuentos y nuevos cursos?

Arreglos Unidimensionales

Los arreglos se utilizan cuando es necesario almacenar varios valores. También se podrían guardar valores en un conjunto de variables simples, pero esto es más engorroso, y más complejo de manejar. En lugar de tener 10 variables de tipo real para guardar las alturas de personas, es más sencillo crear un arreglo de 10 elementos de tipo real, ya que toda la información la manejo con el mismo nombre de variable; y los elementos se diferencian entre sí según el valor que asuma un subíndice asociado al vector.

 En la práctica suele ser necesario procesar conjuntos de datos, como por ejemplo listas de alumnos, docentes, cuentas bancarias, etc. Por ejemplo, si necesitase procesar datos de 5000 alumnos respecto al promedio de inasistencia de ellos, deberíamos tener 5000 variables simple, cada una de ellas contendría un entero que represente este dato (inasistencias).

Si por ejemplo se quisiese ordenar los alumnos por número creciente de inasistencias, para por ejemplo otorgarles un premio, sería imperioso tener todos los datos activos en memoria, y necesitaría otra variable para indicar el orden de los datos (5000 variables enteras más). Mientras que con un arreglo unidimensional de 5000 elementos de tipo entero sería suficiente para contener los datos y una variable más de tipo entero para indicar el orden dentro del arreglo (subíndice).

Ordenado los datos de menor a mayor, en la primer posición del arreglo (índice = 1) tendría la menor inasistencia y en la última posición tendría el número más grande correspondiente al mayor número de falta (índice = 5000). Como queda explicado con esta breve reflexión, es necesario que los lenguajes de programación brinden soporte para mantener juntos (referenciados mediante un mismo identificador) colecciones de datos del mismo tipo.

Entonces ¿qué es una array?

Es una estructura de datos estática y representa un conjunto FINITO Y ORDENADO de elementos del MISMO TIPO DE DATOS. Un Arreglo o array es un conjunto de variables que tiene las siguientes características:

  • • Todas las variables comparten un mismo nombre.
  • • Cada variable se identifica además de por el nombre, por una posición numérica (llamada índice) por cada dimensión definida.
  • • Todas las variables están ordenadas en forma secuencial a partir de 0 o 1 dependiendo de la configuración del programa PseInt. Para los ejemplos estableceremos que la numeración comienza en 1.
  • • Son homogéneas, todas las variables son del mismo tipo.

Lo importante de este tipo de variables son las facilidades que brinda para procesar un conjunto de datos.

Entonces, Un arreglo es un grupo de variables (llamadas elementos o componentes) que contienen valores, todos del mismo tipo. Los arreglos son objetos, por lo que se consideran tipos de referencia.

Excepción

Una excepción indica un problema que ocurre mientras se ejecuta un programa. El nombre «excepción» sugiere que el problema no ocurre con frecuencia; si la «regla» es que una instrucción, por lo general, se ejecuta de forma correcta, entonces el problema representa la «excepción a la regla. El manejo de excepciones nos permite crear programas tolerantes a fallas que pueden resolver (o manejar) las excepciones.

Los tipos de datos pueden ser simples y estructurados.

  • estructuras estáticas, la memoria se gestiona en tiempo de compilación. ARREGLOS Y REGISTROS. Consumen memoria siempre.
  • estructuras dinámicas, la memoria se gestiona en tiempo de ejecución. COLAS, PILAS, LISTAS Y ARBOLES. Consumen memoria solo cuando lo necesitan
  • Unidimensionales (vectores o arreglos lineales)
  • bidimensionales (matrices) o multidimensionales.

La declaracion de un arreglo va en la seccibn tipo, donde indica la contidad de elementos y tipo de dato de la coleeccion. En la seccion var se crean las variables necesarias de esa colección. Una estructura es una colección de datos organizados de cierta manera, y que se caracterizan por las operaciones que se definen sobre ellas

La clasificación en estática o dinámica se basa en la forma de gestionar la memoria del sistema para almacenar un cojunto de elementos del mismo tipo

Las estructuras estáticas requieren de un espacio de memoria antes de comenzar con la ejecución del programa (se use o no), las dinámicas consumen memoria solo si utilizan.

CLASIFICACION

Estática: la memoria se gestiona en tiempo de compilación

  • Arreglos
  • Registros

Dinámica: la memoria se gestiona en tiempo de ejecución

  • Colas
  • Pilas
  • Listas circulares
  • arboles

Dimensión e índice

Simbolicemos una variable como un espacio de almacenamiento en memoria pero démosle una estructura física como si fuese un cajón portaobjetos. Hasta ahora hemos tratado a las variables como elementos individuales, como si fuera un punto en un espacio o sea de dimensión 0 o sin dimensión. Entonces para reconocer a la variable simplemente se la referenciaba por su nombre. Por ejemplo a esta variable la llamaremos caja.

Luego podemos considerar a un arreglo de dimensión uno equivalente a una estructura física de una sola dimensión, o sea a una línea. En este caso podemos simbolizar el arreglo de una dimensión como un segmento de línea. Cada caja se identificará con un número de índice distinto. Establezcamos que el primer índice es 1. En el ejemplo se aprecia un arreglo de 4 cajas: caja[1], caja[2], caja[3] y caja[4]

Más dimenciones

Si pasamos a las dos dimensiones en el espacio nos encontramos con un plano de ejes x e y, pues bien, podemos simbolizar nuestro array bidimensional como un conjunto de cajas alineadas en columnas y flas.  Cada caja se deberá identificar con dos índices, en el ejemplo tenemos un arreglo de 3 flas por 4 columnas. Entonces el arreglo estará compuesto por doce variables identificadas desde caja[1,1] a caja[3,4].

Si agregamos una tercera dimensión podemos pensar en un arreglo de 3 dimensiones alto, ancho, profundidad. Y así podemos seguir agregando las dimensiones que queramos. Todo arreglo tiene asociado un identificador y cada elemento del arreglo es referenciado por la posición que ocupa.

Para referenciar a cada posición del arreglo, se utilizan índices. Los arreglos se utilizan cuando es necesario manipular varios valores como parte de un conjunto. En lugar de tener 1000 variables para guardar nombres, es más sencillo crear un arreglo de 1000 elementos, ya que toda la información se maneja con el mismo nombre de variable y los elementos se identifican de acuerdo con un subíndice asociado al vector.

Vectores

Los vectores se pueden representar gráficamente como muestra la Figura 1, en donde se representa un arreglo unidimensional llamado datos de cuatro elementos. El identificador del arreglo es utilizado para todos los elementos del conjunto, y el valor del índice asociado identifica en forma precisa a los elementos del arreglo. En este ejemplo los elementos del arreglo son números enteros.

Rango del vector:

Es el número de elementosque se pueden asociar a un vectorr.  En el caso de la Figura1, el rango del vector llamado datos es 4.  El rango se debe indicar previamente a su uso dentro de un programa. En pseudocódigo se declara de la siguiente forma:

Algoritmo declaracion_ arreglo 
tipo
		array[límite inferior...límite superior] de <tipo de dato>: <nombre estructura arreglo>
var
		<nombre estructura arreglo>: <nombre variable de tipo arreglo> 
	
Ejemplo: 
Algoritmo declaracion arreglo 
tipo 
		array[1...4] de entero: arreglo_enteros 
arreglo_enteros: datos 
inicio 

Hay una sección llamada tipo, en la cual se declaran las estructuras de datos de arreglos y otros tipos de datos definidos por el usuario. Se usa la palabra reservada array seguido de un par de corchetes con el rango o tamaño del arreglo indicados por el límite inferior y superior. A continuación, se indica el tipo de dato de los elementos del arreglo y el nombre que tiene la estructura de datos definida.  la estructura se llama arreglo_enteros.

En la sección var, se declaran las variables que se utilizarán en el algoritmo, y en este caso se deben declarar las variables que tendrán la estructura del arreglo definido.  el algoritmo utilizará una variable de nombre datos que tiene la estructura del arreglo. Cada elemento de un vector se puede procesar como si fuese una variable simple. Datos[4]  ⭠8 almacena el valor entero 8 en el vector datos en la posición número 4.

Si se desea guardar el valor entero “Federico” en la segunda posición del vector nombres, la instrucción es nombres[2] ⭠“Federico”. La instrucción escribir(datos[4]) muestra por pantalla el contenido de la posición 4 del vector llamado datos.  En el siguiente ejemplo, se crean dos vectores distintos con la misma estructura definida.

Ejemplo 2

Algoritmo declaracion arreglo_2 
tipo 
		array[1...10] de entero: lista 
Var
		lista: origen, destino 
		entero: indice 
inicio

se declaran dos arreglos distintos definidos por las variables origen y destino. De la misma forma que se declara la variable índice de tipo de dato entero, también se declaran las variables origen y destino de tipo de dato lista. El límite inferior no siempre tiene que iniciaren 1, pero es lo más frecuente. Puede ser definido con cualquier otro valor entero, siempre y cuando el rango definido sea correcto. Las siguientes referencias son válidas:

En este caso, el rango del arreglo Pes 6, y a la posición 1 le corresponde el subíndice 0.

Aquí el rango del arreglo Pes 6,y a la posición 1 le corresponde el subíndice -10, a la posición 2 le corresponde el subíndice -11,y así sucesivamente. Las operaciones que pueden realizarse con vectores son:

  • asignación;
  • lectura/escritura;
  • recorrido;
  • ordenamiento;
  • búsqueda.

Las operaciones de lectura y escritura

Las operaciones de lectura y escritura de los elementos de un arreglo lineal, generalmente, se realizan con estructuras repetitivas.

Algoritmo recorrer _ arreglo 
tipo 
	array[1...10] de entero: lista 
var
	lista: datos 
	entero: indice 
Inicio 
	mostrar("lngresar los 10 elementos del arreglo") 
	desde indice <- 1 hasta 10 hacer 
		leer(datos[indice]) 
	fin-desde 
	mostrar("Se muestran los elementos del arreglo") 
	desde indice <-1 hasta 10 hacer 
		escribir(datos[indice]) 
	fin-desde 
fin 

Declaración de una variable de tipo array

Siempre que se va a utilizar un arreglo se deberá especificar al comienzo cual será la dimensión del mismo. Esto se hace con la palabra reservada Dimensión. En el ejemplo de la variable caja de dos dimensiones la sentencia seescribirá: Dimension caja[3,4]

Resolución de problemas usando arreglos unidimensionales

Ejemplo 3

Se desea crear un algoritmo en pseudocódigo que permita ingresar 10 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores que ocupan las posiciones pares por pantalla.

Algoritmo Muestra_posi_par
	tipo
		array [1..10] de entero : dato
	var
		dato : origen entero: índice
inicio
	escribir („ ingresar los 10 elementos del arreglo‟)
	desde índice ⭠ 1 hasta 10 hacer //se toman los valores del teclado 
           leer ( origen [índice])
	fin-desde
	escribir („ Se muestran los elementos de las posiciones pares del arreglo lineal‟)
	desde índice ⭠ 2 hasta 10 inc 2 hacer // se muestran por pantalla los datos del arreglo lineal             
            escribir (origen [índice])
	fin-desde 
fin

Ejemplo 4

Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores positivos que sean pares por pantalla.

Algoritmo Muestra_positivos_par
	tipo
		array [1..20] de entero : dato
	var
                dato : vec entero: índice
inicio
       escribir („ ingresar los 20 elementos del arreglo‟)
       desde índice ⭠ 1 hasta 20 hacer //se toman los valores del teclado 
          leer ( ver [índice])
       fin-desde
       escribir („ Se muestran los elementos positivos pares‟)
       desde índice ⭠ 1 hasta 20 hacer // se recorre los datos del arreglo lineal 
            si (vec [índice] > 0) y (vec [índice] mod 2 = 0) entonces
	        mostrar (vec[índice]) 
            fin-si
        fin-desde
fin

Ejemplo 5

Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores positivos que sean pares por pantalla.

Algoritmo Muestra_positivos_par
tipo
		array [1..20] de entero : dato
var
		dato : vec entero: índice
inicio
	escribir („ ingresar los 20 elementos del arreglo‟)
	desde índice ⭠ 1 hasta 20 hacer //se toman los valores del teclado 
            leer ( ver [índice])
	fin-desde
	escribir („ Se muestran los elementos positivos pares‟)
	desde índice ⭠ 1 hasta 20 hacer // se recorre los datos del arreglo lineal
	          si (vec [índice] > 0) y (vec [índice] mod 2 = 0) entonces 
                       mostrar (vec[índice])
                  fin-si 
        fin-desde
fin

Ejemplo 6

Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y guardar los enteros positivos en otro arreglo del mismo tipo. Mostrar los valores de este segundo arreglo porr pantalla.

Algoritmo Detecta_positivos_arreglo
tipo
		array [1..20] de entero : dato
var
		dato : origen, destino entero: índice, indice2
inicio
	escribir („ ingresar los 20 elementos del arreglo‟)
	desde índice ⭠ 1 hasta 20 hacer //se toman los valores del teclado 
            leer ( ver [índice])
	fin-desde
	//„ Se detectan y guardan los enteros positivos en arreglo destino Indice2 ⭠ 1
	desde índice ⭠ 1 hasta 20 hacer // se recorre los datos del arreglo origen 
             si (vec [índice] > 0) entonces
                 destino[índice2] ⭠ vec [índice] indice2 ⭠ indice2 +1
             fin-si 
        fin-desde
	escribir („Se muestran los elementos del arreglo destino‟) 
        desde índice ⭠ 1 hasta indice2 hacer
		mostrar( destino [índice]) 
	fin-desde
fin

Ejemplo 7

Se desea crear un programa que permita guardar 15 caracteres tomados desde el teclado, el algoritmo deberá contar cuantas letras son mayúsculas. Mostrar este resultado por pantalla.

Algoritmo Cuenta_Mayúsculas
tipo
		array [1..15] de caracter : dato
var
		dato : ar
		entero: índice, cant_May 
inicio
	cant_May ⭠ 0
	escribir („ ingresar los 15 caracteres del teclado‟)
	desde índice ⭠ 1 hasta 15 hacer //se toman los valores del teclado 
             leer ( ar [índice])
	fin-desde
	//„ Se detectan y cuentan las letras mayúsculas 
        desde índice ⭠ 1 hasta 15 hacer
		si ((ar [índice] > „A‟) y ( ar[índice] < „Z‟0)) 
                     entonces cant_May ⭠ cant_May +1
		fin-si 
         fin-desde
         escribir („La cantidad de letras mayúsculas del arreglo es:‟, cant_May) 
fin

Capacidad versus longitud de un array

Tal como lo definimos cuando estudiamos cadenas, haremos una diferenciación entre los conceptos de «capacidad» y «longitud» de un array.

Sea el array a de tipo int [50] entonces:

  • la capacidad es: 50.
  • La longitud de a en principio será 0 y aumentará en la medida en que vayamos agregando elementos al array. A la longitud del array la llamaremos len (abreviatura de length, «longitud» en inglés).

La longitud indica cuántos elementos están siendo contenidos, por lo que, si agregamos elementos al array, debemos incrementar su longitud. En cambio, la capacidad hace referencia al tope físico que, en el caso de a, es de 50 valores de tipo int. Consideremos ahora estas líneas de código:

int a[50];

a[0]=8;

a[1]=4;

a[2]=6;. (https://bit.ly/3czoHA0).

Operaciones sobre array y sus características

Agregar un elemento al array

Esta operación permite agregar un elemento en la primera posición libre del array. Es decir, al final.

Si consideramos que el array está vacío, entonces su longitud (len) será cero y este valor coincidirá con la posición en la que el elemento debe ser agregado. Luego de esto, tendremos que incrementar len, ya que la longitud del array pasará a ser 1.

Desarrollaremos la función agregar que tendrá el siguiente encabezado:

int agregar(int a[], int* len, int v).

En esta función, a es el array en cuya primera posición libre asignaremos el valor v. La función retornará la posición en la que se agregó a v, que siempre coincidirá con el valor de len-1, e incrementará el valor de len, ya que, al agregar un nuevo elemento al array, su longitud debe ser incrementada.

Búsqueda secuencial

Esta operación consiste en recorrer secuencialmente el array para determinar si este contiene o no un determinado valor.

Desarrollaremos la función buscar que recibirá el array, su longitud y el elemento que queremos determinar si está o no contenido dentro del array. La función retornará la posición en la cual el array contiene al elemento que estamos buscando o un valor negativo si el elemento no está contenido dentro del array. El encabezado de la función será el siguiente:

int buscar(int a[], int len, int v).

En ella, a es el array, len su longitud y v el elemento cuyo valor queremos determinar si está o no contenido dentro del array a.

La estrategia para desarrollar la función buscar será la siguiente: recorrer el array comenzando por la posición 0 y avanzando hacia la siguiente posición siempre y cuando no estemos excediendo su longitud y no encontremos lo que estamos buscando.

Buscar y agregar

Esta operación es una combinación de las dos anteriores. La idea es buscar un elemento en un array y retornar la posición en la que se encontró o bien agregarlo al final en caso de no haberlo encontrado. La función buscarYAgregar tendrá el siguiente encabezado:

int buscarYAgregar(int a[], int* len, int v, int *enc)

Asignara true o false en el parámetro enc según el elemento v se encuentre previamente o no en el array a y su valor de retorno representara:

  • si enc es true: la posición en donde a previamente contenía a v.
  • si enc es false: la posición en donde (ahora) a contiene a v.

Insertar un elemento

A través de esta operación, podremos insertar un elemento en una determinada posición del array siempre y cuando esta posición este comprendida entre 0 y len. Llamemos pos a la posición en la que vamos a insertar el elemento v.

El algoritmo consiste en desplazar hacia abajo a todos aquellos elementos comprendidos entre pos y len-1 para dejar libre la posición pos y poder asignar allí a v.

Eliminar un elemento

Esta es la operación inversa a la de insertar un elemento. La idea es eliminar del array al elemento que se encuentre en una posición especificada. El algoritmo consistirá en desplazar hacia arriba a todos aquellos elementos ubicados entre pos+1 y len siendo len la longitud del array y pos la posición del elemento que queremos eliminar. También será necesario decrementar el valor de len porque, luego de eliminar un elemento, la longitud del array habrá disminuido.

Insertar en orden

Esta operación permite insertar un valor v en un array respetando el criterio de ordenamiento que mantienen sus elementos. Es decir, que el contenido del array debe estar ordenado. El algoritmo consiste en recorrer el array comenzando desde la posición 0 y avanzando mientras que no excedamos su longitud y mientras que el elemento que encontramos en la i-esima posición sea menor o igual al que buscamos. Luego, lo insertaremos en la posicion i.

La función insertarEnOrden tendrá el siguiente encabezado:

int insertarEnOrden(int a[], int* len, int v, int* encontro).

Buscar en orden

Esta operación realiza la búsqueda secuencial de un elemento v sobre un array a, considerando que el contenido de a está ordenado. Con esta premisa, no será necesario recorrer el array hasta el final para determinar si contiene o no a v, ya que si durante la recorrida encontramos que a[i] es mayor que v, será porque a no contiene a v.

Desarrollaremos la función buscarEnOrden con el siguiente encabezado:

int buscarEnOrden(int a[], int len, int v, int* enc).

La función debe buscar a v en a. Si lo encuentra, retornará la posición en la que a contiene a v y asignará true al parámetro enc. Si no, asignará false a enc y retornará la posición en la que a debería contener a v para que, si lo fuéramos a insertar, el array continúe manteniendo los elementos en orden.

Buscar e insertar en orden

Esta operación combina las dos operaciones anteriores y permite insertar (en orden) un valor que no esté contenido en el array. Si intentamos insertar un valor repetido, retornará la posición en la cual el array contiene dicho valor.

El encabezado será el siguiente:

int buscarEInsertarEnOrden(int a[], int* len, int v, int* enc).

La función asignará en enc true o false, según el valor v se encuentre o no en el array a y retornará un valor entero cuyo significado será:

  • si enc es true, la posición en la que a contiene a v.
  • Si enc es false, la posición de a en la que se insertó a v.

Teniendo resueltas las funciones buscarEnOrden e insertarEnOrden, el algoritmo que resuelve esta operación será trivial y se limitará a «buscar en orden» a v en a y luego a «insertarlo en orden», en caso de no haberlo encontrado.

Ordenar arrays (algoritmo de la «burbuja»)

Existen diferentes algoritmos a través de los cuales podemos ordenar los elementos contenidos en un array. Estudiaremos el algoritmo más simple (también el menos eficiente), conocido como el «algoritmo de la burbuja». El algoritmo de la «burbuja» consiste en recorrer el array analizando la relación de precedencia que existe entre cada elemento y el elemento que le sigue, para determinar si estos se encuentran ordenados entre sí y, en caso de ser necesario, permutarlos para que queden ordenados. Genéricamente hablando, si a es el array que vamos a ordenar, e i es un valor comprendido entre 0 y len-1, entonces: si a[i] > a[i+1], significa que estos dos elementos se encuentran desordenados entre sí y que habrá que permutarlos.

La enseñanza de los arrays estáticos, dinámicos y listas enlazadas ¿cuál usar? Análisis de códigos

Las listas contiguas como las enlazadas se emplean cuando se desconoce la cantidad de elementos con las que trabajará un programa, y que la selección del tipo de lista (simple, doble, circular) depende de las exigencias del problema, el lenguaje de programación y los conocimientos del programador, y por otro lado, los arrays de tamaño estático se emplean cuando se conoce de antemano la cantidad de elementos que se almacenarán, y esa cantidad no corre el riesgo de ser alterada en tiempo de ejecución del programa.

En la actualidad, es frecuente que los estudiantes de ingenierías, al introducirse en el Proceso de Enseñanza y Aprendizaje de un lenguaje de programación, cometan errores al transformar su algoritmo a código fuente y al identificar las colecciones de datos más recomendadas para la solución de su problema. Estos errores pueden ser, a veces, irremediables, provocando un aumento considerable en su tiempo de aprendizaje, cansancio y posible deserción escolar al sentirse desalentados y considerar que la disciplina no es comprensible para ellos. Por otro lado, la enseñanza de la programación en el contexto universitario, es para los profesores, un gran reto desde lo pedagógico, didáctico y metodológico.

La estructura perfecta

No existe la estructura perfecta para todas las operaciones, aunque si la más recomendada para uno u otro problema a resolver. Al analizar los proyectos informáticos realizados por equipos de estudiantes en el Proceso de Enseñanza y Aprendizaje de la Programación Orientada a Objetos y Estructuras de Datos, junto a los softwares observados en la red de redes se pudo constatar el excesivo uso de las clases ArrayList en Java y List en C#. Ambas poseen como base un array de elementos, frente a la clase LinkedList, disponible en ambos lenguajes, que implementa una lista doblemente enlazada.

Por otro lado, aunque en las disciplinas Estructura de Datos I y II se estudian las listas enlazadas (nodos enlazados) simple, doble y circular; los árboles, colas de prioridad y grafos, estos contenidos resultan ser olvidados, poco o nunca usados en el desempeño profesional de estudiantes, especialistas y profesores de Programación, anteponiendo los arrays de tamaño estático y las listas contiguas. Entonces, ¿Qué son realmente los arrays de tamaño estático y los arrays dinámicos o listas contiguas? ¿Qué insuficiencias tienen los arrays que dieron origen a las listas contiguas y enlazadas? ¿Cuál se debe usar para resolver un problema? ¿Qué criterios se deben tener en cuenta para el empleo eficiente de una u otra estructura de datos?

A continuación, se dará respuesta a las anteriores preguntas, con argumentos basados en la sistematización de los estudios publicados en diferentes revistas especializadas, monografías, libros electrónicos y otras fuentes bibliográficas, unido a la experiencia vivencial de los autores.

Arrays y arrays dinámicos

Un array es una estructura donde se guarda una colección finita de datos del mismo tipo. Se accede a cada elemento individual del array mediante un número entero denominado índice. Cero (0) es el índice del primer elemento y n-1 es el índice del último elemento, donde n, es la dimensión del array. [2] En el presente trabajo a este array se le llamará también array de tamaño estático, por que aceptará siempre una colección finita de datos. A continuación, la representación gráfica de un array de tamaño estático donde se almacenan 10 números enteros, ubicados en posiciones desde la 0 hasta la 9.

Características fundamentales de los arrays

Son colecciones de elementos homogéneos. Aceptan solo un tipo de datos en cada celda de una matriz o vector. Tanto en Java como en C# los arrays se declaran de forma análoga. En ambos lenguajes los arrays son objetos con características individuales y heredan de la clase base Object que es la raíz de todo el árbol de la jerarquía de clases del lenguaje y las construidas por los usuarios. En C# los arrays son objetos de la clase System.Array.

Declaración

Como ya vimos la declaración es así: tipo [ ] identificador; lo que hace es declarar una referencia a un array. En Java existe la clase Arrays que implementa un conjunto de operaciones sobre los arrays. Se pueden crear arrays de objetos de cualquier tipo. La creación de un array, una vez que se conoce su identificador se hace de la siguiente forma: identificador = new tipo [cantidad de elementos]. Ejemplo int [ ] p = new int.

De esta forma se está reservando espacio para los elementos del array de tipo entero y el objeto p puede acceder a cada elemento del array, a través del índice. La memoria asignada es contigua y estática esto puede ocasionar desperdicio de la misma. El programador no necesita estar al tanto de la siguiente o anterior asignación de memoria. Se puede acceder a los datos almacenados a través de un índice y se les puede recorrer con solo incrementarlo. Se les llaman estructuras indexadas.

Proporcionan acceso aleatorio como array [1], array. La inserción y eliminación requieren más de tiempo que en una lista enlazada; En Java y C#, la memoria de un array se asigna en tiempo de ejecución mediante el empleo del operador new. Java verifica el rango de un array y si detecta el ingreso o acceso a un elemento fuera de los índices establecidos, provoca que el programa rompa el tiempo de ejecución generando una excepción.

unidimensionales y multidimensionales

Cuando la memoria esté muy fraccionada, puede ser costoso o tal vez imposible encontrar espacio contiguo para ampliar un array dinámico. Los arrays consumen menos memoria al almacenar el mismo elemento que una lista enlazada porque ella adiciona, además del dato, al menos un campo dedicado a enlazar un nodo con otro. Se clasifican los arrays de tamaño estáticos según su dimensión en unidimensionales y multidimensionales.Como ya vimos la declaración de un array estático bidimensional se realiza de la forma:

tipo [ ][ ]nombre=new tipo[cantidad][cantidad].

Por otro lado, una lista enlazada es una estructura de datos que representa una secuencia de valores, que pueden repetirse más de una vez. Si el mismo valor se repite varias veces, cada ocurrencia está considerada un elemento distinto. En las listas no enlazadas o arrays dinámicos (listas contiguas) los elementos se almacenan en posiciones consecutivas de memoria. Se corresponden con el concepto general de array de la mayoría de lenguajes de programación.

A menudo…

A menudo se representa una lista como una sucesión de elementos entre paréntesis, separados por comas y pueden expresarse como L = (a0, a1, a2, …, an-1), también se representa L = [a, b, c, d, e, ……x]. En este tipo de estructura de datos se identifican ventajas y desventajas en la programación de la solución de un problema.

En las listas contiguas se insertan elementos sin un límite pre establecido, aunque su cambio de tamaño es una tarea costosa, implica copiar su contenido a una nueva zona más grande de memoria, y luego liberar el espacio del array anterior. La inserción o eliminación de un elemento, necesita una traslación de ellos, antes o después del insertado o eliminado.

La figura representa una lista contigua o array dinámico, en el que se adicionan elementos hasta llegar a un máximo permitido, luego para continuar adicionando se realiza una copia de ella. Este proceso se repite continuamente y puede ocupar memoria innecesaria. Así acontece en la clase ArrayList y List de Java y C# respectivamente.

Características de las listas enlazadas

Las listas enlazadas, son secuencias de nodos que se enlazan con apuntadores o referencias a direcciones de memoria “desarrolladas en 1955-56 por Cliff Shaw y Herbert Simon en RAND Corporation, como la principal estructura de datos para


su Lenguaje de Procesamiento de la Información”, fue usado por los autores para desarrollar varios programas relacionados con la inteligencia artificial, incluida la Máquina de la Teoría General, el Solucionador de Problemas Generales, y un programa informático de ajedrez.

En la actualidad, de acuerdo a los softwares observados en la red de redes, la tendencia a la creación de listas enlazadas por la gran mayoría de los programadores en Visual Basic, Java, Python y C# se realiza aprovechando las potencialidades de la Programación Orientada a Objetos, a través de la creación de clases y de referencias a direcciones de memorias de objetos de clases.

Las listas enlazadas poseen las siguientes características:

La información se almacena aleatoriamente, en nodos ubicados en diferentes partes de la memoria de acceso aleatoria (RAM). Basta con conocer la posición del primer nodo, que al menos necesita dos atributos, en uno se guarda la información (dato) y otro contiene la referencia a la dirección de memoria en el que se encuentra el siguiente nodo.

Se accede a cada nodo secuencialmente y no de forma indexada, debido a la interdependencia o vínculo de ellos, por lo que para acceder al último nodo de la lista hay que recorrer los n-1 elementos previos. Se crea cada nodo cuando se hace una solicitud, esto es una ventaja sobre los arrays. La inserción y eliminación son simples y rápidas. Se pueden realizar por cualquier parte de la lista.

Al inicio o al final, después o antes de un determinado nodo, además, se eliminan nodos dependiendo del campo de información o dato que se desea suprimir de la lista. Tienen la facilidad de expandirse y disminuir su tamaño, según se necesite agregar o eliminar elementos en tiempo de ejecución.

La búsqueda en una lista enlazada no ordenada necesita que se recorran todos los nodos hasta encontrar el ítem que se busca antes de llegar a null. Si la lista enlazada está ordenada, siempre que el nodo actual sea mayor que el elemento que se busca, se puede detener la pesquisa automáticamente haciendo uso de un centinela o variable booleana inicializada en false, que cambiará a true cuando se cumpla la condición y se acelerará la pesquisa.

Representación gráfica

Representación gráfica de un nodo de una lista simplemente y doblemente enlazada:

A continuación, la figura 4 muestra una lista enlazada simple donde el último nodo apunta a null, lo cual significa el fin de la lista.

Por otra parte, cuando los nodos tienen un doble enlace, es decir, un enlace al siguiente (dirección sucesora) y otro enlace al nodo anterior (dirección predecesora) como se muestra en la figura 5, entonces se conocen como lista doblemente enlazada.

La lista doblemente enlazada aventaja a la lista simplemente enlazada en su recorrido en ambos sentidos, de izquierda a derecha como de derecha a izquierda, los nodos primero y último apuntan a null, que simboliza el final de la lista. El puntero anterior permitirá el acceso hacia el elemento anterior de la lista, mientras que el puntero siguiente permitirá el acceso hacia el próximo elemento. Su desventaja con relación a las listas simplemente enlazadas es que ocupan más memoria por nodo.

También existen las listas simples y doblemente enlazadas circulares donde el último nodo enlaza con el primero y este enlaza con el último. Así se representa:



Materiales y métodos

La Modelación como método se empleó al elaborar las secuencias de pasos o algoritmos y los códigos en el lenguaje de programación para insertar, imprimir y buscar. La Sistematización y el Análisis Documental de los estudios realizados sobre las colecciones más empleadas en la programación en los lenguajes de programación Java y C#, permitieron al autor identificar lo común y lo diferente entre los arrays y las listas enlazadas, así como la precisión de cuándo deben aplicarse cada una de ellas en la solución de un problema.

La Observación a clases conferencias de Programación, algoritmos, más de 20 códigos de programación, clases prácticas y de laboratorios, permitió a los autores un mayor acercamiento a la creación de códigos de arrays, arrays dinámicos con el empleo de las listas que ofrecen los lenguajes antes citados (ArrayList y List) y listas con el empleo de nodos enlazados.

Para el conocimiento de la evolución de las colecciones, entre ellas, las listas y los arrays, comenzando con los lenguajes de programación C y C++, y luego Java y C#, sus antecedentes, contradicciones y formas de programarlas en el presente, el autor se valió del método Histórico – Lógico. Los procedimientos lógicos del pensamiento Análisis y Síntesis, así como la Inducción y Deducción, proporcionaron a los autores elaborar conclusiones y recomendaciones relacionadas con el empleo de los arrays y las listas enlazadas, aplicables a estudiantes, profesores y programadores.

Resultados

Los principales resultados de las acciones desarrolladas en esta etapa de la investigación se resumen en la obtención de las modelaciones gráficas de los arrays de tamaño estático, dinámicos y las listas enlazadas; la creación de los algoritmos y códigos en el lenguaje Java para la creación de listas enlazadas, puntualizando en la inserción de datos, imprimir y buscar un elemento; los códigos y las recomendaciones metodológicas a estudiantes de Ingeniería Informática y Ciencias de la Computación, profesores de programación y programadores y la identificación de algunas dificultades que se producen en el Proceso de Enseñanza y Aprendizaje de los arrays y las listas enlazadas.

A continuación, se exponen los algoritmos y códigos para para la creación, búsqueda, borrado e impresión de los elementos de una lista doblemente enlazada en el lenguaje de programación Java, adaptable también al lenguaje de programación C#.

Se parte de una clase llamada Estudiante, que posee una clase interna llamada Nodo donde se encapsulan los atributos: ci, nombre, edad, siguiente y anterior. Se desea crear una lista enlazada que almacene los datos de un conjunto indeterminado de estudiantes. Se parte de la hipótesis que se realizarán continuadas inserciones y borrados de elementos en la lista.

Creación de algoritmos para el trabajo con listas enlazadas. Algoritmo general para crear listas con nodos enlazados:

Crear: Una clase externa o clase contenedora llamada Estudiante. Una clase anidada llamada Nodo dentro de la clase Estudiante.

Designar, dentro de la clase interna Nodo las variables que recibirán los datos y las de tipo apuntadores o referencias (anterior e siguiente), de tipo Nodo. Inicializar los datos y las referencias en el constructor de la clase Nodo, las referencias se inicializan a null (siguiente=null y anterior=null). Crear dentro de la clase Estudiante y fuera de la clase interna Nodo las referencias primerNodo y ultimoNodo ambos de tipo Nodo.

La referencia primerNodo contendrá la dirección del primer elemento de la lista y la referencia ultimoNodo contendrá la dirección del último elemento de la lista. Inicializar primerNodo y ultimoNodo dentro del constructor de la clase Estudiante (primerNodo=null y ultimoNodo=null). Crear los métodos de la clase Estudiante (Insertar, Mostrar, Buscar)

Creación de códigos en el lenguaje de programación Java

Algoritmo y código para insertar datos la derecha del primer nodo

Declarar un método con parámetros (definir tipos de parámetros)

Crear un objeto de tipo Nodo (nuevo) invocando su constructor sin parámetros. Con el objeto creado invocamos los atributos de la clase interna Nodo y le asignamos los datos pasados por parámetros. Si el primerNodo es igual a null o vacío, entonces primerNodo y ultimoNodo apuntan a nuevo nodo, sino: El apuntador siguiente del ultimoNodo apunta nuevo (el nuevo nodo). El apuntador anterior del nuevo Nodo apunta para el último. El nuevo nodo será el ultimoNodo de la lista, esperando otro nuevo.


Se crea un nodo que recibe los datos entrado por parámetros (ci), (nom) y (ed). A ese nodo se le llama nuevo. Si primerNodo apunta a null entonces se hace que primero apunte a nuevo y si no es así, entonces se comienza a insertar a la derecha haciendo que ultimoNodo.siguiente apunte a nuevo, que nuevo.anterior apunte a ultimoNodo y siempre el último nodo apunta a nuevo. Inserción de nodos a la derecha del primero. Elaboración propia.

Algoritmo y código para insertar datos a la izquierda del primer nodo

Declarar un método con parámetros (definir tipos de parámetros). Crear un objeto de tipo la clase interna Nodo (nuevo) invocando su constructor sin parámetros. Con el objeto creado invocamos los atributos de la clase interna Nodo y le asignamos los datos pasados por parámetros. Si el primerNodo apunta a null o vacío entonces: El primerNodo y ultimoNodo apuntan para nuevo (el nuevo nodo) sino es así: El apuntador anterior del primerNodo apunta para nuevo (el nuevo nodo). El apuntador siguiente de nuevo apunta para el primerNodo. El nuevo nodo será el primerNodo de la lista

Se crea un nodo que recibe los datos entrados por parámetros carnet de identidad, nombre y edad. A ese nodo se le llama nuevo. Si primerNodo apunta a null entonces se hace que primerNodo apunte a nuevo y si no es así, entonces se comienza a insertar a la izquierda haciendo que primerNodo.anterior apunte a nuevo, que nuevo. Siguiente apunte a primer Nodo y finalmente el primerNodo apunta a nuevo.

Inserción de nodos a la izquierda del primero. Elaboración propia.


En el artículo trabajo no se ha trabajado con los métodos de accesos de cada atributo para racionalizar espacio en el mismo.

Algoritmos y códigos para imprimir datos del primero al último

Declarar un método con retorno de tipo String sin parámetros. Crear un objeto de tipo Nodo llamado percorre y se inicializa en primerNodo o en ultimoNodo y una variable do tipo String llamada mostrar inicializada en “ ”. Crear una estructura repetitiva (while) que iterará mientras la variable de percurso (percorre) sea diferente de null. Concatenar (mostrar+=percorre. datos, de acuerdo a los datos que se deseen mostrar). La variable percurso recibe percurso.siguiente o percurso.anterior para las próximas iteraciones de ciclo

Algoritmos y códigos para buscar datos en la lista no ordenada Algoritmo:

Crear: Un método con parámetro (dato a buscar) con retorno (boolean). Una variable unEstudiante de tipo Nodo (inicializada en el primerNodo). Un ciclo (while) que iterará mientras la variable de unEstudiante sea diferente de null. Una estructura condicional (if).

Si el dato a buscar es igual a un dato encontrado en la lista entonces retornar true. Cerrar el ciclo. Si no lo encontró retornar false

La elaboración de un buen algoritmo, es una tarea tan atrayente y necesaria como la creación de un programa con el empleo de un lenguaje determinado. Por tales razones, para profesores, estudiantes o programadores es aconsejable reconocer las siguientes interrogantes antes de iniciar un algoritmo: ¿Qué datos o elementos iniciales se poseen? ¿Qué se desea obtener? ¿Qué otros datos necesitarían? ¿Cómo alcanzar el resultado? ¿Qué fórmula(s) debo emplear? ¿Qué otro procesamiento se necesita?

Analiza el problema que pretendes resolver, identifica las posibles vías de solución y verifica si necesitarás de un array con tamaño estático, array dinámico o una lista enlazada para resolverlo.

Resolución de problemas

Para resolver los problemas relacionados con las antedichas estructuras de datos, los profesores deben vincularlas con situaciones tomadas de las empresas u organizaciones, con el propósito de estimular la atención del estudiante universitario.

Si en el problema que has de resolver identificas un número finito de elementos a almacenar y recorrer, emplear una lista enlazada será una mala práctica de programación. Empleas un array de tamaño estático.

Tanto para recorrer un array como una lista contigua, puedes emplear la estructura repetitiva for (tipo variable: array) en Java o en C# el foreach (tipo variable in arrray). Ambas estructuras repetitivas fueron diseñadas para recorrer colecciones. En C#, las clases List o ArrayList tienen una funcionalidad similar, pero se considera que List ofrece un mayor rendimiento y tiene seguridad de tipos.

En Java, si se identifica que habrá muchas búsquedas en listas grandes, es aconsejable implementar la interface List instanciándola en un ArrayList. Ejemplo: List listaElementos = new ArrayList().

Si por lo contrario, las operaciones que más se realizarán serán las inserciones y eliminaciones en listas grandes, entonces es aconsejable implementar la interface List instanciándola en un LinkedList. Ejemplo: List listaElementos = new LinkedList().

Discusión

El estudio realizado, desde la fase exploratoria demostró la necesidad de profundizar en la conceptualización, y determinación de los elementos comunes y divergentes entre los arrays de tamaño estáticos, dinámicos y las listas enlazadas.

Se emplearon clases anidadas, pueden existir varios niveles de anidamiento. Una clase interna es otro miembro más de la clase contenedora o clase externa. Las clases anidadas permiten la creación de un código más legible y compacto, y aumentan la encapsulación ya que pueden ocultarse de otras distintas a la clase que la contiene, aunque pueden acceder a atributos de su clase exterior sin que estos dejen de ser privados.

Por otra parte, para garantizar un doble recorrido de las listas, hacia adelante y/o hacia atrás, o dado un elemento, conocer rápidamente el anterior y siguiente, entonces, lo más recomendado fue trabajar con listas doblemente enlazadas.

Los arrays dinámicos en Java y C#, ofrecen acceso en tiempo constante a los elementos de la lista, pero si deseas añadir o borrar en cualquier posición que no sea la última es necesario mover los elementos. Además, si el arreglo ya está lleno es necesario crear uno nuevo con mayor capacidad y copiar los elementos existentes para continuar la introducción de datos. Una lista contigua es más apropiada para cantidades pequeñas de datos, donde la memoria continua esté siempre disponible.

Las listas enlazadas aventajan a las listas contiguas en que la inserción y extracción de nodos se realizan con un gasto de recursos independiente al tamaño de la lista. No hay necesidad de grandes cantidades de memoria contigua. El uso de memoria se adapta dinámicamente al número de datos almacenados en la lista en cada momento.

Conclusiones

En el proceso de enseñanza y aprendizaje de los arrays, listas contiguas y listas enlazadas es recomendable escribir el algoritmo que soluciona el problema, luego modelar gráficamente la estructura y finalmente escribir el código en el lenguaje de programación.

Los arrays se emplean cuando se conoce de antemano la cantidad de elementos que se almacenarán, y esa cantidad no corre el riesgo de ser alterada en tiempo de ejecución del programa.

Tanto las listas contiguas como las enlazadas se emplean cuando se desconoce la cantidad de elementos con las que trabajará un programa. La selección del tipo de lista (simple, doble, circular) depende de las exigencias del problema, el lenguaje de programación y los conocimientos del programador.

Las listas enlazadas convienen ser empleadas antes que las listas contiguas dinámicas y los arrays con tamaño estático cuando en una aplicación se necesita realizar cuantiosas operaciones de inserción y eliminación de elementos. Las listas doblemente enlazadas, aunque requieren más espacio por nodo por causa de sus referencias siguiente y anterior, ofrecen una mayor facilidad para recorrerlas al permitir el acceso secuencial en ambas direcciones.

Problemas propuestos

Problema 1

Calcular el promedio de 50 valores almacenados en un vector. Determinar además cuantos son mayores que el promedio, imprimir el promedio, el número de datos mayores que el promedio y una lista de valores mayores que el promedio.

Problema 2

Llenar dos vectores A y B de 45 elementos cada uno, sumar el elemento uno del vector A con el elemento uno del vector B y así sucesivamente hasta 45, almacenar el resultado en un vector C, e imprimir el vector resultante.

Problema 3

Llenar un vector de 20 elementos, imprimir la posición y el valor del elemento mayor almacenado en el vector. Suponga que todos los elementos del vector son diferentes.

Problema 4

Almacenar 500 números en un vector, elevar al cuadrado cada valor almacenado en el vector, almacenar el resultado en otro vector. Imprimir el vector original y el vector resultante.

Problema 5

Almacenar 300 números en un vector, imprimir cuantos son ceros, cuantos son negativos, cuantos positivos. Imprimir además la suma de los negativos y la suma de los positivos.

Problema 6

Almacenar 150 números en un vector, almacenarlos en otro vector en orden inverso al vector original e imprimir el vector resultante.

Problema 7

Se tienen almacenados en la memoria dos vectores M y N de cien elementos cada uno. Hacer un algoritmo que escriba la palabra “Iguales” si ambos vectores son iguales y “Diferentes” si no lo son. Serán iguales cuando en la misma posición de ambos vectores se tenga el mismo valor para todos los elementos.

Problema 8

Se tiene el vector A con 100 elementos almacenados. Diseñe un algoritmo que escriba “SI” si el vector esta ordenado ascendentemente o “NO” si el vector no esta ordenado

Problema 9

Diseñe un algoritmo que lea un numero cualquiera y lo busque en el vector X, el cual tiene almacenados 80 elementos. Escribir la posición donde se encuentra almacenado el numero en el vector o el mensaje “NO” si no lo encuentra. Búsqueda secuencial.

Problema 10

Diseñe un algoritmo que lea dos vectores A y B de 20 elementos cada uno y multiplique el primer elemento de A con el ultimo elemento de B y luego el segundo elemento de A por el diecinueveavo elemento de B y así sucesivamente hasta llegar al veinteavo elemento de A por el primer elemento de B. El resultado de la multiplicación almacenarlo en un vector C.

Problema 11

Diseñe un algoritmo que almacene en un vector llamado FIB[100] los 100 primeros números de la serie fibonacci.

No te detengas, sigue avanzando

Aquí tienes un propósito para este 2024 que debes considerar seriamente: si has querido mejorar tus habilidades en hacking, Ciberseguridad y programación ahora es definitivamente el momento de dar el siguiente paso. ¡Desarrolla tus habilidades aprovechando nuestros cursos a un precio increíble y avanza en tu carrera!

detengas, sigue avanzando

Aquí tienes un propósito para este 2024 que debes considerar seriamente: si has querido mejorar tus habilidades en hacking, Ciberseguridad y programación ahora es definitivamente el momento de dar el siguiente paso. ¡Desarrolla tus habilidades aprovechando nuestros cursos a un precio increíble y avanza en tu carrera!

Python Practicando. Desde 0 hasta Desarrollador en Python

Aprende Python, donde iniciamos desde 0, sin conocimientos previos hasta desarrollar aplicaciones con mucha practica!

Calificación: 4,6 de 5 (20.833 calificaciones) 249.493 estudiantes Creado por Alvaro Chirou • 1.800.000+ Enrollments WorldwideWalter Coto || +450,000 Estudiantes Español.

Lo que aprenderás

  • Ejercitar la lógica de programación
  • Comprender cómo la vida cotidiana puede ser fácilitada o simulada con código
  • Aprender programación desde cero
  • Usar Visual Studio Code como Editor de Código
  • Conocer y aprender el lenguaje de programación Python
  • Ser un programador desde cero, sin conocimiento en otro lenguaje o con algo previo
  • Mejorar las habilidades de programación, mejorar procesos y fácilitar la comprensión de código
  • Preparar un entorno dónde programar en Python
  • Operaciones aritméticas y jerarquía de Python
  • Manejo de cadenas en Python
  • Digitar datos por teclado con Python
  • Mostrar Datos por Pantalla al usuario en Python
  • Operadores Relacionales de Python
  • Operadores Lógicos de Python
  • Condicionales en Python
  • Estructuras de Datos: Listas, Tuplas y Diccionarios
  • Iteraciones y bucles repetitivos de Python
  • Segmentar Código y hacerlo más eficaz con las Funciones en Python
  • Gestionar posibles errores que puedan dar tus programas
  • Programación Orientada a Objetos
  • HTML y CSS
  • Selenium Web Driver con Python
  • Ejercitar todo lo Aprendido con Ejercicios

Este curso incluye:

  • 25,5 horas de vídeo bajo demanda
  • 21 artículos
  • 148 recursos descargables
  • Acceso en dispositivos móviles y TV
  • Certificado de finalización

Python es Hoy uno de los lenguajes más utilizados por Excelencia.

Esto se debe por su simpleza al momento de Desarrollar aplicaciones.

Por su capacidad de procesamiento a altas velocidades con grandes volúmenes de información.

Es un increíble lenguaje con el cual si no sabes programar, podrás aprender.

Y si ya sabes desarrollar, te aconsejo aprenderlo ya que en el mercado cada vez se solicitan más desarrolladores en Python.

Aspirar al trabajo que desean, o mejorar sus ingresos con un aumento de salario.

Python se utiliza para muchisimas cosas como:

  • Machine Learning
  • Data Science
  • Inteligencia Artificial.
  • Y mucho más!

En este curso te acompañare en el proceso por el cual aprenderás las bases del lenguaje, para luego determinar qué camino quieres seguir.

Te invito que me acompañes a conocer este Gran Lenguaje!

Aprende con nuestros más de 100 cursos que tenemos disponibles para vos

¿Te gustaría enterarte de cuando lanzamos descuentos y nuevos cursos?

La imagen tiene un atributo ALT vacío; su nombre de archivo es image.png

Sobre los autores

Álvaro Chirou

Yo soy Álvaro Chirou, tengo más de 20 Años de experiencia trabajando en Tecnología, eh dado disertaciones en eventos internacionales como OWASP, tengo más de 1.800.000 estudiantes en Udemy y 100 formaciones profesionales impartidas en la misma. Puedes serguirme en mis redes:

  • Facebook
  • Twitter
  • LinkedIn
  • Telegram
  • TikTok
  • YouTube
  • Instagram

Laprovittera Carlos

Soy Laprovittera Carlos. Con más de 20 años de experiencia en IT brindo Educación y Consultoría en Seguridad de la Información para profesionales, bancos y empresas. Puedes saber más de mi y de mis servicios en mi sitio web: laprovittera.com y seguirme en mis redes:

  • LinkedIn
  • Twitter
  • Telegram
  • Instagram

¿Quieres iniciarte en hacking y ciberseguridad pero no sabes por dónde empezar? Inicia leyendo nuestra guia gratuita: https://achirou.com/como-iniciarse-en-ciberseguridad-y-hacking-en-2024/ que te lleva de 0 a 100. Desde los fundamentos más básicos, pasando por cursos, recursos y certificaciones hasta cómo obtener tu primer empleo.

SIGUE APRENDIENDO GRATIS CON NUESTRAS GUIAS

Cómo Iniciarse en Hacking y Ciberseguridad en 2024

Curso Gratis Linux – Capitulo 1 – Introducción a Linux

Curso Gratis de Redes – Capitulo 1 – Tipos de redes y servicios

Como iniciarse en TRY HACK ME – Complete Beginner #1



OSINT #1 Más de 200 Search Tools