Está en la página 1de 17

Lenguaje C++

Arreglos 6
06.01 Arreglo de una Dimensión
Un arreglo arr de una dimensión (objeto) es una colección de datos del mismo tipo, en el papel podemos representar un areglo de 3
elementos:
2 4 6 8 10 12
0 1 2 3 4 5 // índices
A las posiciones del arreglo se les llama índices, comienzan en 0 y terminan en 5 (uno menos que el número de elementos).
Un arreglo es un objeto muy sencillo; sin embargo tiene muchas aplicaciones; en este capítulo aprenderemos las más frecuentes e
importantes.

Se pueden definir de diferentes modos:


int arr[6]; // arreglo de 6 elementos
int n= 6, arr[n];

#define N 3 // define la constante N con el valor 3. Atento no va el signo = ni el ; final.


int arr[N]; // tiene 3 elementos

int n;
scanf("%d", &n);
int nn[n]; // arreglo de n elementos

Se asigna valores uno por uno: arr[0] = 2; arr[1] = 4; ….. // comienza en 0

Se puede definir y asignar:


int arr[6] = {2, 4, 6, 8, 10, 12}; // Define y asigna valores a todo el arreglo
int arr[6] = {2, 4}; // Define y signa valores a los elementos 0 y 1
int arr[] = {2, 4, 6}; // Define un arreglo de 3 elementos y asigna valores
// Número de elementos de arr = sizeof(nn)/sizeof(int) = 3
int n = 6, arr[n]; // Define a arr con 6 elementos
arr = {2, 6, 4}; // Error de compilación: debe asignar valores a cada elemento
int mm[3] = {1,2,3,4}; // Error de compilación: demasiados valores
arr[0] = 2+1; // Asigna 3 al elemento 0
scanf("%d", &arr[1]); // Lee y asigna valor a arr[1]
for(i=0; i<6; i++) arr[i] = 2*i+1; // Asigna valores a todo el arreglo: 1, 3, 5, 7, 9, 11

Se puede cometer errores de compilación, ejemplo:


int arr[2] = {1}; // compila; pero arr[1] tendrá un valor desconocido: lo que encuentre en su posición de memoria.
int arr[-2]; // no compila
int n=-2, arr[n]; // compila, habrá corrupción de datos
int arr[2] = {2, 1, 3}; // no compila: 3 está demás
int n=2, arr[n] = {2, 1, 3}; // compila, habrá corrupción de datos: 3 está demás

Ubicación física de datos de un programador al momento de ejecución


Los datos se ubican en una memoria RAM (Random Access Memory) que es como un hilo, el sistema operativo asigna un segmento de
memoria al programa:

arr RAM
Segmento de programa

El compilador no controla si el índice se sale del arreglo: <0 ó >tamaño-1


En tiempo de ejecución:
Si el índice sale del arreglo pero permanece dentro del segmento se producen errores lógicos (corrupción de datos).
Si el índice sale del segmento se produce un error de violación de segmento, el programa se aborta y no se sabe en que línea.
La corrección de estos errores son responsabilidad del programador y lo puede hacer con un poco de atención. El compilador o en
tiempo de ejecución se podrían detectar y avisar algunos errores; pero esto haría que el programa sea menos flexible y más lento al
ejecutarse. En el capítulo de apuntadores aprenderemos a manejar la memoria en detalle.

PÁGINA: 1
Lenguaje C++

Se puede navegar (recorrer) un arreglo de diferentes modos, por ejemplo:


Salidas
for(i=0; i<6; i++) printf("%d ", arr[i]); // 2 4 6 8 10 12
for(i=0; i<6; i+=2) printf("%d %d ", arr[i], arr[i+1]); // 2 4 6 8 10 12
i=0; while(i<6) printf("%d ", arr[i++]); // 2 4 6 8 10 12
for(i=0; i<6; i+=2) printf("%d ", arr[i]); // 2 6 10
for(i=5; i>0; i--) printf("%d ", arr[i]); // 12 10 8 6 4 2
for(i=0, j=5; i<j; i++, j--) printf("%d %d ", arr[i], arr[j]); // 2 12 4 10 6 8
printf("%d ", arr[rand()%6]); // rand()%6 es un número aleatorio entre 0 y 5 ≡ 1 (por ejemplo)
// se imprime: 4

Interpretaciones de un arreglo
Se puede interpretar como:
Una función : arr: Indices → valores, ejemplo: arr[2] = 6
Una serie histórica, en la que el índice representa al tiempo y arr puede representar a cualquier variable: para t=2, arr[2] = 2.

Una relación inversa: Valores → Indices, ejemplo: 6 → arr[2], 3 → arr[..] no existe índice,

Sensores de índices, ejemplo: sensor de primos menores o iguales a 10:


arr[10] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0} // si arr[i] == 1, i es primo
índice 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
for(i=0; i<10; i++) if(arr[i]) printf("%d", i); // ≡ 2, 3, 5, 7 son primos.

Flujo de trabajo
1) El programador define un arreglo de una dimensión, ejemplo:
int arr[exp]; // arr tiene exp (expresión ent o char > 0) elementos int
// si exp < 0 compila; pero se producirán errores por corrupción de datos.
Ejemplo:
int n = 2, arr[n+1]; // arr tiene 3 elementos
Cada elemento del arreglo se comporta como una variable simple:
arr[0] = 2; // asigna 2 al primer elemento
arr[1] = 6;
arr[2] = 4;
printf("%d\n", arr[0]); // imprime 2
for(i=0; i < 4; i++) printf("i: %d", arr[i]+1);

2) El compilador valida la sintaxis de las instrucciones, una por una; NO valida la lógica del programa.
3) El sistema operativo aloja el arreglo en la RAM y opera con los valores, conoce la dirección de inicio del arreglo y su tamaño en bytes;
pero no conoce el número de elementos; sin embargo lo puede calcular mediante:
Sizeof(arr)/sizeof(int) ≡ 3
arr
2 6 4
0X ….4 // dirección de inicio del arreglo
Posiciones (índices): [0] [1] [2] // el primer elemento inica en 0
Solo existe físicamente lo que está escrito en negro, lo que está en rojo son notas para el lector.

Notas:
• Tanto al definir como al asignar valores a un arreglo se utilizan expresiones enteras o char:
int , n = 2, arr[n+1] = {1, 2, 3}; // define un arreglo de longitud 3;
arr[n-1] = n+2; // asigna 4 a arr[1]
• Los elementos no asignados, contienen el valor que encontraron en la memoria física.
arr, Atento al índice i

Responsabilidades del programador


a) Asignar valores a los elementos del arreglo antes de usarlos; no asignar es un error de lógica severo que no es controlado por el
compilador ni detectado en tiempo de ejecución, sino se asigna previamente, se tomará el valor que contiene la dirección física del
elemento, por ejemplo:
#include <cstdio>
main(){
int arr[3];
arr[0] = 7; // asigna valor a arr[0]
printf("%d\n",arr[0]); // usa el valor de arr[0]
printf("%d\n",arr[1]); // No asignó valor a arr[1] con anterioridad
PÁGINA: 2
Lenguaje C++
}
Salida:
7 // correcto
32764 // imprevisible: es un valor que estaba en la memoria.
b) Mantenerse dentro de los límites del arreglo: Si el índice se sale del rango (a la izquierda o derecha), es un error de lógica SEVERO,
ya que se corrompen o toman datos fuera de control; el compilador no reporta error; pero en tiempo de ejecución puede suceder:
a) El programa termina normalmente pero los resultados pueden estar errados y el desarrollador no lo sabe; es un error difícil
de detectar.
b) El programa termina con un mensaje de error “violación de segmento -memoria asignado al programa- y no dice en que
instrucción sucedió el error, también es un error difícil de detectar.
Si nos damos cuenta del error, podemos revisar el código del programa; pero no es seguro de encontrarlo. Se recomienda imprimir
trazas (valores de variables) en líneas cercanas (antes y después) de donde parece ocurrir el error, se ejecuta y verifica los
valores de las variables o el programa termina con “violación de segmento”.

Veamos un ejemplo de una ejecución:


01 #include <cstdio>
02 main(){
03 int arr[3];
04 arr[-1] = 7; // fuera de rango, no se reporta error en tiempo de ejecución
05 printf("%d\n",arr[-1]);
06 arr[3] = 8; // fuera de rango, no se reporta error en tiempo de ejecución
07 printf("%d\n",arr[3]);
08 arr[-4000] = 9; // fuera de rango, no se reporta error en tiempo de ejecución
09 printf("%d\n",arr[-4000]);
10 arr[4000] = 10; // fuera de rango, va a producir error en tiempo de ejecución
11 printf("%d\n",arr[4000]);
12 }
Salida:
7 // línea 05: funcionó
8 // línea 07: funcionó
9 // línea 09: funcionó
Violación de segmento (`core' generado) // línea 11: no funcionó.
Si ejecuta otra vez el mismo programa los resultados pueden ser distintos.

06.02 Generar Números Aleatorios


Ingresar valores de prueba desde el teclado es tedioso, podríamos asignar números al azar llamando a la función rand() que genera
números distribuidos uniformemente entre 0 y RAND_MAX (un número entero enorme).
rand() utiliza un algoritmo sencillo y muy rápido para generar una secuencia de números pseudo-aleatorios; que parecen aleatorios
pero no lo son, ya que son generados por un algoritmo que utiliza un número para generar el siguiente. Si ejecutamos un programa
varias veces siempre aparece la misma secuencia de números (ya que se usa el mismo algoritmo) y esto esto no es ni siquiera pseudo-
aleatorio; para superarlo se asigna un número inicial (semilla) diferente en cada ejecución, se llama una sola vez, al inicio:
srand(time(NULL)); // time(NULL) = número de segundos que han transcurrido desde el 1 de enero de 1970
Ejemplo:
#include<cstdio>
#include<cstdlib> // Librería requerida para rand() y srand()
#include <ctime> // Librería requerida por time()
main(){
srand(time(NULL)); // se llama una sola vez al inicio y genera una “semilla”
printf("%d\n", rand()); // genera el primer pseudo-aleatorio
printf("%d\n", rand()); // genera el segundo pseudo-aleatorio
}
Salida: 1166072965
38321763

Generar números aleatorios en un rango:


Rango (m <= n, enteros) función
[0, n-1] rand()%n
[0, n] rand()%(n+1)
[m, n] rand()%(n-m+1) + m
[0, 1] con 3 decimales (float)(rand()%1001)/1000

PÁGINA: 3
Lenguaje C++

// 06_01.c: Defina un arreglo de 4 elementos, asígnele valores aleatorios


entre 20 y 32, liste el arreglo y finalmente, imprima 3 elementos al azar
#include <cstdio>
#include<cstdlib>
#include <ctime> // Librería requerida por time
main() {
int a=20, b=32, ab, i, arr[4];
ab = b-a+1;
srand(time(NULL)); // semilla
printf("Asignación de 4 valores aleatorios entre 20 y 32: ");
for (i=0; i<4; i++){
arr[i] = rand()%ab + a; // asina valores
printf("%d ", arr[i]);
}
printf("\nSelección de 3 elemenos al azar: ");
for (i=0; i<3; i++) printf("%d ", arr[rand()%4]); //
printf("\n");
}
Salida:
Asignación de 4 valores aleatorios entre 20 y 32: 22 23 31 23
Selección de 3 elemenos al azar: 23 23 31

06.03 Paso de argumento de tipo arreglo a una Función


Si pasa un elemento de un arreglo arr a una función, se pasa su valor, como lo hace con cualquier variable, ejemplo:

void mitad(int n){ // n recibe el valor 4, no conoce nada sobre su procedencia
n = n/2; // n vale 2; pero el valor de arr[1] no cambiará
}
main(){
int arr[4] = {2 , 4, 6, 8};
mitad(arr[1]); // llamando pasa el valor 4
// arr[1] == 4 no es cambiado en mitad( )

}

Si pasa un arreglo arr a una función, NO se pasan todos sus elementos; se pasa solo un valor: la dirección del primer elemento de arr;
esto permite compartir todo arr entre la main() y la función llamada: si se modifican los elementos de arr dentro de la función, se
modifican también dentro de main( ); a diferencia de lo que sucede cuando se pasa una variable simple: NO se modifica.
Ejemplo: Sea arr = {2, 4, 6, 8}, calcular la mitad de sus elementos
#include <cstdio>
void mitad(int, int arr[]);
main(){
int i, arr[4] = {2, 4, 6, 8}; // arr inicia en 0xf...0
mitad(4, arr); // pasa: 4, y la dirección de arr (hexadecimal): 0xf...
for(i=0; i<4; i++)
printf("%d ", arr[i]); // arr == {1, 2, 3, 4}
}
void mitad(int n, int arr[ ]){ // n recibe valor 4, arr recibe la dirección 0xf...0
// void mitad(int n, int arr[n]){ // También es válido
int i;
for(i=0; i < n; i++) arr[i] /=2; // calcula la mitad a arr.
}

Atento a los detalles del paso de argumentos a parámetros de funciones, es una fuente de errores muy frecuente:
• Debe pasar el número de elementos y el arreglo porque la función llamada no tiene modo de saberlo:
mitad(4, arr); // llamando

void mitad(int n, int arr[ ]){ // definición de mitad

PÁGINA: 4
Lenguaje C++
• Al ejecutar se corresponden tipos y número de datos en la secuencia 1, 2, 3 4 del siguiente ejemplo:
//Prototipos válidos: // 4: Concuerda en tipo y número de parámetros con suma( ) en 3
int suma(int n , int arr[ ]); // el más usado
// int suma(int m, int n[ ]);
// int sumar(int b, int a[]);
// int sumar(int, int []);
// Prototipos no válidos:
// suma(int n, float m[ ]);
// float suma(int n, int m);

main(){
int n=4, arr[ ] = {1, 2, 3, 4}; // 1: Define variables
// llamadas válidas
int s = suma(4, arr); // 2: llama a suma(): arr[ ] es int, y tiene 4=n elementos
suma(n, arr);
float media = suma(n, arr)/(float)n;
/* Llamadas no válidas:
suma(arr);
suma(1,4);
suma(4, {1,2,3,4});
*/
}
int suma(int n, int arr[ ]){ ... return 10;} // 3: Define a suma( ): n es int , arr[ ] es int.

// 06_02.c: Calcular la media de los elementos de un arreglo.


#include<cstdio>
int suma(int , int []); // Prototipo
main(){
int n=4, arr[4] = {1,2,3,4};
printf("La media es: %f\n", suma(n, arr)/(float)n); // Llama a suma( )
}
int suma(int n , int nn[]){ // Define a suma( )
int i, sum =0;
for(i=0; i<n; i++) sum += nn[i];
return sum;
}
Salida:
La media es: 2.500000

/* 06_03.c: Leer un número n > 1, definir un arreglo nn[n] y asignarle valores


aleatorios entre 0 y 99, reportar nn, calcular el mínimo, la suma y la media de
sus elementos. */
#include<cstdio>
#include<ctime>
#include<cstdlib>
void asignar(int n, int nn[]);
void calcular(int n, int nn[]);
void reportar(int n, int nn[]);
main(){
int n;
printf("Tamaño del arreglo: "); scanf("%d", &n); // se ingresó: 4
int nn[n];
asignar(n, nn);
printf("Valores del arreglo:\n");
reportar(n, nn);
calcular(n, nn);
}
void asignar(int n, int nn[]){
int i;
srand(time(NULL)); // Semilla de rand()
for(i=0; i<n; i++) nn[i] = rand()%100; // valores entre 0 y 99
}
void reportar(int n, int nn[]){
PÁGINA: 5
Lenguaje C++
int i;
for(i=0; i<n; i++) printf("%d\t", nn[i]);
printf("\n");
}
void calcular(int n, int nn[]){
int i, suma=0, min=nn[0];
for(i=0; i<n; i++){
suma += nn[i];
if (min > nn[i]) min=nn[i];
}
printf("\nMínimo del arreglo = %d", min);
printf("\nSuma del arreglo = %d", suma);
printf("\nMedia del arreglo = %f\n", suma/(float)n);
}
Salida:
Tamaño del arreglo: 4
Valores del arreglo:
69 66 20 66

Mínimo del arreglo = 20


Suma del arreglo = 221
Media del arreglo = 55.250000

06.04 Estructuras de Repetición y Arreglos


Los estructuras de repetición se aplican frecuentemente a arreglos. A continuación varios ejemplos ilustrativos. Revise con atención el
código en rojo.
/* 06_04.c: Definir un arreglo de longitud 5, leer un número m, llamar a la función:
int buscar(int n, int m, int arr[])
para buscar a m en el arreglo, si lo encuentra retorna verdad, en caso contrario retorne falso.*/
#include<cstdio>
int buscar(int n, int m, int arr[]);
main(){
int n = 5, arr[5] = {12, 3, 45, 7, 22}, m;
printf("Ingrese un entero > 0: ");
scanf("%d", &m); // Ingrese 3
if(buscar(n, m, arr)) printf("%d está en el arreglo.\n", m);
else printf("%d No está en el arreglo.\n", m);
}
int buscar(int n, int m, int arr[]){
int i;
for(i=0; i<n; i++) if(arr[i]==m) return 1;
return 0;
}
Salida:
Ingrese un entero > 0: 3
3 está en el arreglo.

Ejemplo:
Problema: Hallar todos los números primos menores o iguales a n=26
Análisis: Los números primos son: 2, 3, 5, 7, 11, 13, 17, 19 Y 23
Diseño 1(algortimo de Eratóstenes):
Toma los números arr[ ] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}:
1) busca el primer valor k = 2 != 0, y asigna 0 a todos los elementos múltiplos de k hasta el final:
K=2: Arr[ ] = {2, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 0, 15, 0, 17, 0, 19, 0, 21, 0, 23, 0, 25, 0}
2) busca el siguiente valor k = 3 != 0, y asigna 0 a todos los elementos múltiplos de k hasta el final.
K=3: Arr[ ] = {2, 3, 0, 5, 0, 7, 0, 0, 0, 11, 0, 13, 0, 0, 0, 17, 0, 19, 0, 0, 0, 23, 0, 25, 0}
Repiti el paso 2 para k= 5, 7, 11 y 13
K=11: Arr[ ] = {2, 3, 0, 5, 0, 7, 0, 0, 0, 11, 0, 13, 0, 0, 0, 17, 0, 19, 0, 0, 0, 23, 0, 0, 0}
Al conjunto final se le llama Criba de Eratóstenes: Todos los números distintos de 0 son primos
Diseño 2 (Algoritmo que usa arreglos): Utilizaremos la misma idea de Eratóstenes; pero aprovechando un dato que no era
evidente para él: los índices del arreglo -que representarán a los números-, nuestro programa será más veloz. Partamos de:
arr : {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
PÁGINA: 6
Lenguaje C++
Indice i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
1) Tomemos i=2 y asignemos arr[i] =0 para todos los índices múltiplos de i:
arr : {0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}
Indice i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
2) busca el siguiente índice i tal que arr[i]=1 → i=3 y asignemos arr[i] =0 para todos los índices múltiplos de i:
arr : {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0}
Indice i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
Repetir el paso 2: i = 5, 7, 11, y 13:
arr : {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0}
Indice i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//* 06_05.c: Generar la criba de Eratóstenes para n=26
#include<cstdio>
void eratostenes(int n, int arr[]);
main(){
int n = 26+1, arr[n], i;
eratostenes(n, arr);
printf("Números primos: ");
for(i=0; i<n; i++) if(arr[i]) printf("%d ", arr[i]);
}
void eratostenes(int n, int arr[]){
int i, j, n2=n/2;
arr[0] = arr[1] = 0;
for(i=2; i<n; i++) arr[i]=1; // partida
for(i=2; i<n2; i++) if(arr[i]) for(j=2; i*j<n; j++) arr[i*j]=0; // asignar 0
}
Salida: Números primos: 2 3 5 7 9 11 13 17 19 23

/* 06_06.c: Leer un número n > 1, definir dos arreglo nn1[n] y nn2[n], asígnar valores
aleatorios entre 10 y 20 a nn1; asignar valores a nn2 a partir de nn1, invirtiendo los
elementos, ejemplo:
si: nn1 = {12, 17, 20, 16} → nn2 = {16, 20, 17, 12}
Reporte nn1 y nn2.
*/
#include<cstdio>
#include<ctime>
#include<cstdlib>
void asignar (int n, int nn1[]);
void invertir(int n, int nn1[], int nn2[]);
void reportar(int n, int nn[]);
main(){
int n;
printf("Tamaño del arreglo: "); scanf("%d", &n); // se ingresó = 5
int nn1[n], nn2[n];
asignar(n, nn1);
invertir(n, nn1, nn2);
printf("Valores del arreglo: ");
reportar(n, nn1);
printf("Valores invertidos: ");
reportar(n, nn2);
}
void asignar(int n, int nn[]){
int i;
srand(time(NULL)); // Semilla de rand()
for(i=0; i<n; i++) nn[i] = rand()%11+10; // valores entre 10 y 20
}
void invertir(int n, int nn1[], int nn2[]){
int i, j;
for(i=0, j = n-1 ; i<n; i++, j--) nn2[j] = nn1[i];
}
void reportar(int n, int nn[ ]){
int i;
for(i=0; i<n; i++) printf("%d\t", nn[i]);
printf("\n");

PÁGINA: 7
Lenguaje C++
}
Salida:
Tamaño del arreglo: 5
Valores del arreglo: 17 14 12 19 15
Valores invertidos: 15 19 12 14 17

Ejemplo: Escribir un programa que analice el arreglo {2, 3, 4, 5, 9, 20, 22, 50, 12, 15, 16, 17}, el cual contiene números enteros positivos,
encuentre todas las ternas (a, b, c) que formen un triángulo e indique si es rectángulo:
a) imprima los lados del triángulo e indique si es rectángulo.
b) imprima la cantidad total de triángulos .
Ejemplo: para los 5 primeros elementos del arreglo {2, 3, 4, 5, 9}, la salida será:
2, 3, 4
2, 4, 5
3, 4, 5 rectángulo
Triángulos = 3

Diseño: ¿Cómo encontrar todas las ternas en {2, 3, 4, 5, 9,}?


índice: 0, 1, 2, 3, 4
Las ternas (a, b, c) serían :
2, 3, 4 2, 3, 5 2, 3, 9
2, 4, 5 2, 4, 9
2, 5, 9
3, 4, 5 3, 4, 9
3, 5, 9
4, 5, 9
Las cuales se obtienen con 3 for() anidados:
int n = 5; // 5 elementos
for(i=0; i<n-2; i++) // 0 <= i < 3 para a
for(j=i+1; j<n-1; j++) // i+1 <= j < 4 para b
for(k=j+1; k<n; k++){ // j+1 <= k < 5 para c
// la terna será: (arr[i], arr[j], arr[k])

}

// 06_07.c: Encontrar todos los triángulos posibles que se pueden formar con los elementos de un arreglo
de números positivos
#include<cstdio>
main(){
int i, j, k, a, b, c, n = 12, sumaT = 0, arr[12] = {2, 3, 4, 5, 9, 20, 22, 50, 12, 15, 16, 17};
printf("Triángulos:\n");
for(i=0; i<n-2; i++) // análisis de ternas
for(j=i+1; j<n-1; j++)
for(k=j+1; k<n; k++){
a = arr[i]; // primer elemento de la terna
b = arr[j]; // segundo elemento de la terna
c = arr[k]; // tercer elemento de la terna
if(a+b>c && a+c>b && b+c>a){ // prueba si es triángulo
printf("%d,\t%d,\t%d", a, b, c);
sumaT++;
a *= a;
b *= b;
c *= c;
if(a+b==c || a+c==b || b+c==a) // prueba si es rectángulo
printf(" \trectángulo");
printf("\n");
}
}
printf("Triángulos = %d\n", sumaT);
}

PÁGINA: 8
Lenguaje C++
Salida:
Triángulos:
2, 3, 4
2, 4, 5
2, 15, 16
2, 16, 17
3, 4, 5 rectángulo
3, 20, 22

Triángulos = 59

06.05 Ordenar un Arreglo


Un problema clásico e importante es ordenar ascendente/descendente-mente los elementos de un arreglo. Se resuelve de distintas
formas: bubble (burbuja) sort, insertion sort, selection sort, quick (rápido) sort, merge (mezcla) sort, Shell (Apellido del inventor) sort, etc.

1) El algoritmo más sencillo es el de la burbuja (bubble sort); que emplea la siguiente estrategia:
Supongamos que ordenaremos ascendentemente al arreglo arr[5] = {17, 16, 18, 10, 19}; longitud n = 5.
Recorreremos el arreglo con dos índices i y j: arr[i] arr[j]:
0<= i <n-1 Arreglo: {17, 16, 18, 10, 19}
Indices j: 0 1 2 3 4
0 Coloca el mínimo (del arreglo) en la posición 0 // intercambia arr[0] con arr[j]
for(j = i+1; j<n; j++) if(arr[i] > arr[j]) {temp = arr[i]; arr[i] = arr[j]; arr[j] = temp } {10, 17, 18, 16, 19
1 Coloca el mínimo (de la parte derecha) en la posición 1: // intercambia arr[1] con arr[j] {10, 16, 18, 17, 19}
2 Coloca el mínimo (de la parte derecha) en la posición 2: // intercambia arr[2] con arr[j] {10, 16, 17, 18, 19}
3 Coloca el mínimo (de la parte derecha) en la posición 3: // intercambia arr[3] con arr[j {10, 16, 17, 18, 19
Diseño del for(i=0; i< n-1; i++)
algoritmo for(j = i+1; j<n; j++) if(arr[i] > arr[j]) {
temp = arr[i]; arr[i] = arr[j]; arr[j] = temp // intercambia arr[i] con arr[j]
}
//Este algoritmo suele ser el más lento porque se hacen muchos intercambios de valores

// 06_08.c: Ordenar ascendentemente un arreglo, método de la burbuja


#include<cstdio>
void ordenar(int n, int arr[]);
void reportar(int n, int arr[]);
main(){
int n = 5, arr[5] = {17, 16, 18, 10, 19};
printf("Arreglo original:\n");
reportar(n, arr);
ordenar(n, arr);
printf("\nArreglo ordenado:\n");
reportar(n, arr);
}
void reportar(int n, int arr[]) {
int i;
for(i=0; i<n; i++) printf("%d\t", arr[i]);
printf("\n");
}
void ordenar(int n, int arr[]) {
int i, j, temp;
for(i=0; i< n-1; i++)
for(j = i+1; j<n; j++)
if(arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Salida:
Arreglo original :
PÁGINA: 9
Lenguaje C++
17 16, 18, 10, 19
Arreglo ordenado:
10 16, 17, 18, 19

2) El método insertion sort, es muy natural para los humanos, lo usamos para ordenar fichas, supongamos que las fichas son:
fichas: arr = {17 12 15 18 9 }
indices i: 0 1 2 3 4 (n = 5)
Ordenamos de izquierda a derecha: repitiendo un proceso de 3 pasos:
temp: 12 15 18 9
1 3 3
3 1 3 1 1
arr: { 17 → 12 15 18 9} → {12 17 →15 18 9}→ { 12 15 17 18 9} →{ 12 15 17 18 → 9 } → {9 12 15 17 18}
i: 0 2 1 22 2 3 24

Diseño del algoritmo:


for(i=1; i<n; i++) { // varía i
temp = arr[i]; // Paso 1: se desplaza arr[i] a tem
for(j=i; j>0 && temp<arr[j-1]; j--) arr[j]=arr[j-1]; // Paso 2: desplazan "varias" fichas un lugar a la derecha
arr[j]=temp; // Paso 3: se desplaza tem al arr[j] "adecuado"
}

3) El selection sort suele ser el más rápido y emplea la siguiente estrategia:


Supongamos que ordenaremos ascendentemente al arreglo arr[5] = {17, 16, 18, 10, 19}; longitud n = 5.
Recorreremos el arreglo con dos índices i y j y busca el elemento mínimo de una parte del arreglo (es un poco elaborado):
0<= i <n-1 Arreglo: {17, 16, 18, 10, 19}
Indices j: 0 1 2 3 4
0 Busca el elemento mínimo (del arreglo) y lo pone en la posición 0
imin = i;
for(j=i+1; j<n; j++) if (arr[imin] > arr[j]) imin = j; // busca el elemento mínimo
if(i<imin) { // lo intrecambia con la posición 0
temp = arr[imin];
arr[imin] = arr[i];
arr[i] = temp;
} {10, 16, 18, 17, 19}
1 Coloca el mínimo (de la parte derecha) y lo pone en la posición 1: {10, 16, 18, 17, 19}
2 Coloca el mínimo (de la parte derecha) y lo pone en la posición 2: {10, 16, 17, 18, 19}
3 Coloca el mínimo (de la parte derecha) y lo pone en la posición 3: {10, 16, 17, 18, 19}
Diseño del for(i=0; i< n-1; i++){
algoritmo imin = i;
for(j=i+1; j<n; j++) if (arr[imin] > arr[j]) imin = j; // busca el elemento mínimo de la parte derecha
if(i<imin) { // lo intrecambia con la posición 0, 1, 2,.. i
temp = arr[imin];
arr[imin] = arr[i];
arr[i] = temp;
}
}

4) El quick (rápido) sort utiliza la estrategia divide y vencerás en modo recurrente: elije un pivot dentro del arreglo, por ejemplo el último
elemento, y divide el arreglo en dos partes: los menores o iguales que el pivot y los mayores; para cada elemento repite el proceso,
en modo recurrente, hasta que cada parte tenga dos elementos, ejemplo:

PÁGINA: 10
Lenguaje C++

fuente: https://www.geeksforgeeks.org/quick-sort/
El arreglo ordenado se obtine coleccionando los pivots de izquierda a derecha: {10, 30, 40, 50, 70, 80, 90}. buscando el algoritmo en
la dirección tenemos:
#include<cstdio>
void quickSort(int arr[], int low, int high);
int partition (int arr[], int low, int high);
void swap(int *m, int *n);
main(){
int arr[] = {10, 80, 30, 90, 40, 50, 70};
quickSort(arr, 0, 6); // índices de 0 a 6
for(int i=0;i<7; i++) printf("%d\n", arr[i]);
}
void quickSort(int arr[], int low, int high){ // función recursiva
int pi;
if (low < high) {
pi = partition(arr, low, high); // pi is partitioning index, arr[pi] is now at right place
quickSort(arr, low, pi - 1); // Before pi
quickSort(arr, pi + 1, high); // After pi
}
}
int partition (int arr[], int low, int high){
int pivot, i, j;
pivot = arr[high]; // pivot (Element to be placed at right position)
i = (low - 1); // Index of smaller element
for (j = low; j <= high- 1; j++) // If current element is smaller than the pivot
if (arr[j] < pivot) {
i++;
swap (&arr[i], &arr[j]);
}
swap (&arr[i + 1], &arr[high]);
return (i + 1);
}
void swap(int *m, int *n){ // usa apuntadores: lo verá en el siguiente capítulo
int k = *m;
*m = *n;
*n = k;
}

5) El merge sort utiliza la estrategia divide y vencerás a tres niveles:


Nivel 1: divide en modo recurrente el arreglo hasta que tenga dos o un elementos
Nivel 2: ordena los sub-arreglos de dos elementos
Nivel 3: compone (merge) los sub-arreglos por pares en modo recursivo
Diseño conceptual:

Nivel 1

Nivel 2

Nivel 3

Puede buscar el algoritmo en internet.

PÁGINA: 11
Lenguaje C++
6) El Shell (apellido del autor) sort utiliza funciones recursivas; en internet puede encontrar videos que representan el diseño del
algoritmo y los programas que lo desarrollan.

7) El heapsort puede ser consultado en internet, una dirección interesante que muestra el diseño es:
https://www.youtube.com/watch?v=jPRLy0zudI8
Para el desarrollo se utilizan arboles binarios y funciones recursivas, y también puede buscar en internet.

En los casos de ordenamiento anteriores, normalmente hemos ordenado de izquierda a derecha, también se puede ordenar de derecha
a izquierda, o combinando:
una pasada (i = 0) a derecha→ una pasada (k = n-1) a izqueirda →
una pasada (i = 1) aderecha → una pasada (k = n-2) a izquierda → ...
suele ser más rápido.

Si hay información de la tendencia de los elementos, un algoritmo puede aprovecharla y ser más veloz.

Aplicaciones de los arreglos ordenados


Si tenemos un arreglo ordenado ascendentemente:
arr = {2, 3, 3, 3, 6, 6, 7, 10} // tamaño n = 8
índices: 0 1 2 3 4 5 6 7
Hay numerosas aplicaciones
1) Buscar en modo lineal si un número num dado está en el arreglo: Se inicia en arr[0] y se vefifica si arr[i] == num para 0 <= i < 8
2) Buscar en modo binario si un número num dado está en el arreglo: utiliza la estrategia divide y vencerás y recursión:
a) divide el arreglo en la mitad izquierda y la derecha, con índices izq=0, der=7, cen=(der-izq)/2=3.
b) verifica si num == arr[cen]: num está en la posición cen → fin.
si num > arr[cen]: aplica el paso (a) para la mitad derecha
si num < arr[cen]: aplica el paso (a) para la mitad izquierda
si es imposible subdividir el arreglo: num no está en arr.
#include<cstdio>
main(){
int n= 8, arr[8]={2, 3, 3, 3, 6, 6, 7, 10};
int izq,der,cen,num, encontrado = 0;
printf("Ingrese un número a buscar: ");
scanf("%d",&num);
izq=0;
der=n-1;
while (izq<=der){
cen=(izq+der)/2;
if (num==arr[cen]){encontrado = 1; break;}
if (num>arr[cen]) {izq=cen+1; cen=(izq+der)/2;}
else {der=cen-1; cen=(izq+der)/2;}
}
if(encontrado) printf("num %d encontrado posicion %d\n",num, cen);
else printf("num %d no encontrado\n",num);
}

3) Aplicaciones estadísticas como: Calcular la frecuencia de ocurrencia de los elementos. La salida será:
Elemento Frecuencia
2 1
3 3
6 2
7 1
10 1

Diseño: Contar la frecuencia de los elementos:


El arreglo se agrupará en: {2, 3, 3, 3, 6, 6, 7, 10}
Frecuencias: 1 3 2 1 1

A este punto, es muy ilustrativo recordar que una estructura de repetición está formada por 5 partes:
1: Inicio de variables: var1, var2, …
2: Condición de repetición del bloqueInstrucción.
3: Bloque o instrucción que se repite usando var1, var2, … y otras.
4: Variación de var1, var2, …
5: fin de repetición.

PÁGINA: 12
Lenguaje C++
Las cuales se comentan en el programa:
// 06_09.c
#include<cstdio>
main(){
int arr[ ] ={2,3,3,3,6,6,7,10}, n=8, i, ant, fre; printf("Elemento Frecuencia\n");
for(i=1, ant= arr[0], fre=1; i<n; i++) // 1; 2; 4
if (arr[i]==ant) fre++; // 3
else{
printf("%d\t %d\n", ant, fre);
ant = arr[i];
fre = 1;
}
printf("%d\t %d\n", ant, fre); // 5
}
Salida: La solicitada

06.06 Arreglo de dos Dimensiones


Un arreglo de dos dimensiones es una colección de datos del mismo tipo, ordenados como matriz, ejemplo:
1 2 // arreglo de 3 x 2 enteros con valores
arr = 6 7
12 13

Definición:
int arr[3][2];
Se puede definir y asignar, siempre que al menos una dimensión sea constante:
int arr[3][2] = {{1, 2}, {6, 7}, {12 , 13}};
int arr[3][2] = {1, 2 , 6, 7, 12 , 13};
int m=3, arr[m][2] = {1, 2 , 6, 7, 12 , 13};
int n=2, arr[3][n] = {1, 2 , 6, 7, 12 , 13};
int const m=3, n=2; arr[m][n] = {1, 2 , 6, 7, 12 , 13};

int m=3, n=2, arr[m][n] = {1, 2, 6, 7, 12 , 13};


Compila y ejecuta; pero solo la primera fila será bien asignada. En el capítulo de apuntadores resolveremos este problema.
En este caso: se define arr y luego se asigna a cada elemento por separado.

La longitud en una dimensión, es el número de elementos en esa dimensión, ejemplo la longitud, en la dimensión 1, de arr es 3.
Los valores se alojan iniciando en la posición [0,0] y terminan en [longitu1–1, longitud2-1].

Responsabilidades del desarrollador


• Asignar valores a los elementos del arreglo antes de operar con ellos; si no lo hace los valores con que opera no son válidos y
no se dará cuenta de ello.
• No violar los límites de las dimensiones de los arreglos porque corromperá los datos y no se dará cuenta de ello; puede
terminar el programa con un error de “violación de segmento”;

Ejemplos:
Printf("\n arr[0][0] = %d, arr[0][1] = %d", arr[0][0], arr[0][1]); // Salida: arr[0][0] = 1, arr[0][1] = 2
arr[0][0] = 6; // Asigna 6 al primer elemento [0,0]
arr[-1][0] = 4; // compila, pero hay problemas en tiempo de ejecución
arr[4][5] = 5; // compila, pero hay problemas en tiempo de ejecución

Atención:
Puede definir y asignar: int m=3, n=2, arr[3][2] = {1, 2 , 6, 7, 12 , 13}; // manejo estático de dimensiones

También compila: int m=3, n=2, arr[m][n] = {1, 2 , 6, 7, 12 , 13}; // manejo paramétrico de dimensiones
pero al momento de ejecutar, solo los valores de la primera fila: 1, 2 , 6 serán correctos; la segunda fila tendrá valores inesperados;
para verificarlo haga un print(“...”, arr[i][j]) del arreglo. Este problema lo resolveremos en el capítulo de apuntadores.

PÁGINA: 13
Lenguaje C++
Paso de argumento arreglo a una función
Si pasa un elemento de un arreglo arr[ ][ ] a una función, se pasa su valor, como lo hace con cualquier variable, ejemplo:

void mitad(int n){ // n recibe el valor 4, no conoce nada sobre su procedencia
n = n/2; // n = 4/2; pero el valor de arr[0][1] no cambiará
...
}
main(){
int arr[2][3] = {2 , 4, 6, 8, 10, 12};
mitad(arr[0][1]) ; // llamando pasa el valor 4

// arr[0][1] ≡ 4, no cambia su valor
}

Si pasa un arreglo arr[ ][ ] completo a una función, no se pasan todos sus elementos; se pasa solo un valor hexadecimal: la dirección
del primer elemento arr[0][0]; esto permite compartir todo arr entre la main() y la función: si se modifican los elementos de arr dentro de la
función, se modifican también dentro de main( ); a diferencia de lo que sucede cuando se pasa un elemento específico: no se
modifica.
en main( ) arr[3][2] = {2, 3, 6, 8, 10, 12} .
en mitad( ) recibe el arreglo y le saca la mitad, luego arr = {1, 2, 3, 4, 5, 6}.
regresa a main() y verifica los valores de arr = {1, 2, 3, 4, 5, 6}; cosa que no sucede si pasará los elementos uno por uno:
#include <cstdio>
void mitad(int m, int n, int arr[][2]); // prototipo
main(){
int arr[3][2] = {2, 4, 6, 8, 10, 12};
mitad(3, 2, arr); // llamando
// arr = {1, 2, 3, 4, 5, 6} se sacó la mitad
}
void mitad(int m, int n, int arr[][2]){ // m = 3, n= 2
// Restricción: es obligatorio indicar la segunda dimensión [2]; sino no compila, ver la Nota al final
// void mitad(int m, int n, int arr[3][2]) También compila
int i, j;
for(i=0; i < m; i++) for(j=0; j < n; j++) arr[i][j] /=2;
}
El motivo de la restricción anterior es que la función llamada no conoce las longitudes de las dos dimensiones de arr y exige que se le de
la longitud de la segunda dimensión para poder ubicar la matriz en la memoria. Esto es una grave limitación de la parametrización que
será resuelto más adelante, en el capítulo de apuntadores.
Ejemplo:
// 06_10a.c : Hallar la media de arr[ ][ ] en main().
#include<cstdio>
main(){
int arr[3][2] = {1, 2, 6, 7, 12 , 11}, i, j;
float media = 0;
for(i=0; i < 3; i++)
for(j=0; j < 2; j++) media += arr[i][j];
printf("\nLa media es: %f\n", (float)media/(2*3));
}
Salida: La media es: 6.50000

// 06_10b.c : Hallar la media de arr usando la función media()


#include<cstdio>
void media(int n, int m, int nn[ ][2]);
main(){
int arr[3][2] = {1, 2, 6, 7, 12 , 11}, i, j;
media(3, 2, arr);
}
void media(int m, int n, int nn[ ][2]){ // ATENTO: La segunda dimensión [ ][2] es obligatoria;
int i, j, media = 0;
for(i=0; i < m; i++)
for(j=0; j < n; j++) media += nn[i][j];
printf("\n La media es: %f\n", media/((float)m*n)); // atento: se hace el casting: (float) m*n
}

PÁGINA: 14
Lenguaje C++
Salida:
La media es: 6.50000

06.07 Arreglo n (>2) Dimensional


Un arreglo de n dimensiones es una ampliación de un arreglo de dos dimensiones: es una colección de datos del mismo tipo, ordenados
como matriz n-dimensional, ejemplo:
int arr[3][2][2] = {1, 2 , 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // arreglo de 3 x 2 x 2 enteros con valores asignados.
// int arr[3][2][2] = { {{1, 2}, {3, 4}}, {{5 , 6}, {7 ,8}}, {{9 , 10}, {11, 12}}}; es equivalente a la instrucción anterior

Se puede definir y asignar, siempre que la primera o al menos dos dimensiones sean constantes:
int int m=3, n=2, k=2, arr[3][2][k] = {1, 2 , 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

int int m=3, n=2, k=2, arr[m][3][k] = {1, 2 , 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // error
En este caso: se define arr y luego se asigna a cada elemento por separado

La longitud en una dimensión, es el número de elementos en esa dimensión, ejemplo la longitud, en la dimensión 1, de arr es 3.
Los valores se alojan iniciando en la posición [0][0]... y terminan en [longitud1–1][longitud2-1]...

Responsabilidades del programador


Las mismas que para arreglos con dos dimensiones, ejemplos:
printf("\n arr[0][0][0]= %d, arr[0][0][1] = %d", arr[0][0][0], arr[0][0][1]); // Salida: arr[0][0][0] = 1, arr[0][0][1] = 2

arr[0][0][0] = 6; // Asigna 6 al primer elemento [0][0][0]


arr[-1][0][1] = 4; // compila, pero hay problemas en tiempo de ejecución por violación de límite en la dimensión 1
arr[4][3][1] = 5; // compila, pero hay problemas en tiempo de ejecuciónpor violación de límite en las dimensiones 1 y 2

Paso de argumento arreglo a una función


Se aplican las mismas reglas que para arreglos de dos dimensiones:
Si pasa un elemento de un arreglo a una función, se pasa su valor, como lo hace con cualquier variable.
Si pasa un arreglo arr completo a una función, no se pasan todos sus elementos; se pasa solo un valor hexadecimal: la
dirección del primer elemento de arr; esto permite compartir todo arr entre la main() y la función: si se modifican los elementos
de arr dentro de la función, se modifican también dentro de main( ); a diferencia de lo que sucede cuando se pasa un elemento
específico: no se modifica.
Ejemplo:
// 06_10c.c: Hallar la media de arr[ ][ ][ ] en la main().
#include<cstdio>
main(){
int arr[3][2][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, i, j, k;
float media = 0;
for(i=0; i < 3; i++)
for(j=0; j < 2; j++)
for(k=0; k < 2; k++) media += arr[i][j][k];
printf("\nLa media es: %f\n", media/12.0); // atento: divisor: 12.0.
}
Salida: La media es: 6.50000

// 06_10d.c: Hallar la media de arr usando la función media():


#include<cstdio>
void media(int l, int m, int n, int nn[ ][2][2]);
main(){
int arr[3][2][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
media(3, 2, 2, arr);
}
void media(int l, int m, int n, int nn[ ][2][2]){ // RESTRICCION: Las dimensiones [ ][2][2] son obligatorias
// void media(int l, int m, int n, int nn[3][2][2]){ también es válida
int i, j, k, media = 0;
for(i=0; i < l; i++)
for(j=0; j < m; j++)
for(k=0; k < n; k++) media += nn[i][j][k];
printf("\nLa media es: %f\n", media/((float)l*m*n)); // atento al casting: (float) l*m*n

PÁGINA: 15
Lenguaje C++
}

Salida:
La media es: 6.50000
El motivo de la restricción anterior es que media() no conoce las longitudes de las dimensiones del arreglo, podrían ser: 3 x 2 x 2; 2 x 3 x
2; 2 x 2 x 3; 6 x 2 x 1; etc; por eso exige la segunda y tercera longitudes.

06.08 Resumen de las Aplicaciones más Frecuentes de los Arreglos


Es muy importante que utilice funciones para programar las aplicaciones; en este momento estamos trabajando con arreglos sencillos, lo
cual le facilita para ganar destreza en el paso de argumentos a parámetros, más adelante los arreglos serán más complejos y se
requerirá que sea un experto pasando argumentos a parámetros. Las aplicaciones más frecuentes son las siguientes:
1) Leer, validar datos leídos, calcular y escribir para cada elemento de un arreglo, ejemplo: Lea dos enteros m y n mayores que 0,
defina la matriz arr de m x n; lea los datos, ejecute cálculos e imprima la entrada y los resultado de los cálculos.
2) Leer, validar datos leídos, hacer cálculos estadísticos de todo el arreglo, ejemplo: Lea dos enteros m y n mayores que 0, defina la
matriz arr de m x n; lea los datos, imprima la matriz, haga cálculos estadísticos sobre sus elementos (menor, mayor, índice en el
que ocurren, la media, etc.)e imprímalos.
3) Leer arreglos y tomar grupos de elementos que cumplen cierta condición, ejemplo: dado a[5] = {10, 5, 12, 4, 7}; liste todos los
triángulos que se pueden definir con los elementos de a.
4) Leer, validar datos de arreglos, hacer operaciones con arreglos, ejemplo: leer dos arreglos a1 y a2, defina un arreglo b = a1 + a2;
imprima a1, a2 y b.
5) Ordenar arreglos de 1 dimensión; ordenar las filas de una matriz según los datos de una columna; leer datos de un arreglo y a
medida que se leen mantenerlos ordenados.
6) Problemas pos-ordenamiento: Luego de ordenar uno o más arreglos, se requieren saber la mediana, la moda, el número de veces
que se repiten los elementos; otro ejemplo: dados dos arreglos a1 y a2 ordenados, imprimir los datos de a1 y a2 de tal modo que
aparezcan ordenados como si fueran un solo arreglo ordenado que contiene a a1 y a2.

No es la idea que usted aprenda de memoria la solución a estos problemas "tipo"; sinó que:
• Tenga una panorámica de las aplicaciones generales de los arreglos.
• Siga una estrategia de solución: entienda bien el problema (análisis); plantee un modelo de solución (diseño): entienda la lógica,
simule la realidad, por ejemplo para ordenar, use fichas y ordénelas manualmente; programe: interpreta el diseño en el lenguaje
C++ y finalmente verifique la matriz de casos de prueba.
• Estas aplicaciones de los arreglos numéricos, también se aplicarán en arreglos de caracteres, apuntadores y estructuras, que serán
estudiadas más adelante; por lo tanto este es el momento para desarrollar una buena plataforma de conocimientos aplicables a
futuro.

06.09 Preguntas de Teoría


1) ¿Qué es un arreglo de una dimensión, cuál es la sintaxis para definir y asignar valores a un arreglo, muestre dos ejemplos
distintos?
2) Sea la definición:
int n, arr[3];
¿Qué valores tienen los elementos de arr?
¿Cuál es el rango de los índices de arr, que sucede si nos excedemos fuera del rango?
3) Sea la definición:
int arr1[3] = {1}, arr2[]={1, 2, 3}, n=2, arr3[n], arr4[n]= {1, 2} ;
¿Qué valores tienen los elementos arr1[1] y arr1[]2
¿Cuántos elementos tiene arr2?
¿Está bien definido arr3?
¿Está bien definido arr4, por qué?
4) ¿Qué tipo de números aleatorios generamos en C++ ? Escriba un programa para generar números aleatorios, luego simule dos
lanzamientos de un dado, genere 3 números aleatorios float en [0, 1]
5) De un ejemplo en el que define y llama a una función pasando como argumento un arreglo, ¿será necesario pasar el número de
elementos?, ¿Cuál es la diferencia de pasar una variable y un arreglo en una función?
6) ¿Qué estructura de programación utiliza para recorrer arreglos? de ejemplos de recorrido ascendente y descendete.
7) Escriba el diseño de dos algoritmos que ordenan arreglos.
8) ¿Cuál es la interpretación gráfica de un arreglo de dos dimensiones, que cuidados debe tener con las dos dimensiones?, ¿que
dificultades hay para pasar un arreglo de dos dimensiones a una función?
9) Escriba un programa que defina un arreglo de 3 dimensiones, asigne valores y utilice una función para duplicar los valores del
arreglo.

06.10 Ejercicios de Programación


Resuelva los ejercicios e imprima los resultados:
PÁGINA: 16
Lenguaje C++
1) Si se escribe main():
#include<cstdio>
main(){
int arr[3][2][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
printf("\n La media de arr es: %f", media(arr, 3, 2, 2)); // Resultado: La media de arr es 6.50000
}
Complete la función media(…).

2) Lea n, genere un arreglo de esa longitud con números aleatorios entre 1 y 20 y calcule: el mínimo, el máximo, la media y la
varianza. Ordene el archivo y calcule la mediana.

3) Se tiene:
int vec1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, vec2[10];
Utilice un for () { .. } para asignar valores a vec2 a partir de vec1, de tal modo que los valores queden en orden inverso: 10, 9, 8, 7,
6, 5, 4, 3, 2, 1.

4) Resuelva el problema anterior utilizando el siguiente for():


for(i=0, j = 9; i < n/2; i++, j--) {….}

5) Defina e imprima el vector fac[n]; asigne valores: fac[i] = i! (factorial de i).

6) Defina las matrices: m1[m][m], m2[m][m], m3[m][m] y m4[m][m], m entre 2 y 20.


Asigne valores:
m1 y m2: genere aleatorios entre 10 y 20
m3 = mt1 + mt2,
M4 = m1 x m2 (producto de matrices).
Imprima todo.

7) Lea una matriz temp[4][12] que contiene datos de temperatura mes a mes de 4 años a partir del año 2013: Reporte los promedios
anual y mensual en el siguiente formato:
Promedio anual
Año: 2013 2014 2015 2016
Promedio: nn nn nn nn

Promedio mensual
Mes: Enero Febrero Marzo ...
Promedio: nn nn nnn

8) Dado el arreglo aa[8] = {10, 2, 5, 6, 3, 7, 6, 4} ordénelo ascendentemente para que quede: {2, 3, 4, 5, 6, 6, 7, 10} y luego
descendentemente para que quede: {10, 7, 6, 6, 5, 4, 3, 2}.
Sugerencias: complete el código

for(i=0; i < 7; i++) // algoritmo de la burbuja
for(j=i+1; j < 8; j++)
if(aa[i] > aa[j]) {
tem = aa[i];
aa[i] = aa[j];
aa[j] = tem;
}

9) Lea un arreglo aa[8] = {10, 2, 5, 6, 3, 7, 6, 4} clasifique en otro arreglo ab[8] para que queden primero los números pares: {10, 2, 6,
6, 4, 5, 3, 7).
10) Sea la matriz:
int arr[3][2]; Dele valores:
12 2
arr = 6 7
1 11
Ordene las filas de arr por la columna 1 para obtener:
1 11
arr = 6 7
12 2

PÁGINA: 17

También podría gustarte