You are on page 1of 11

4

ESTRUCTURAS DE DATOS (I):


ARRAYS. CADENAS DE CARACTERES
En captulos anteriores se ha estudiado el concepto de datos de tipo simple (entero, real y
carcter). A veces, los datos a tratar en un programa no son elementos individuales de informacin,
sino que existe cierta relacin entre ellos. En esos casos, los lenguajes de programacin permiten
trabajar con estructuras de datos, es decir, colecciones de datos ms simples con relaciones
establecidas entre ellos. Estas estructuras de datos posibilitan, por un lado, representar la
informacin de una manera ms natural y clara y, por otro, un tratamiento de la informacin ms
cmodo y eficiente. En este captulo se tratarn dos de las estructuras de datos ms habituales en
programacin: los arrays y las cadenas de caracteres.

4.1 INTRODUCCIN
Una estructura de datos es una coleccin de datos caracterizada por su organizacin y por las
operaciones definidas sobre ella. Los tipos de datos utilizados para declarar estructuras de datos se
denominan tipos compuestos y se construyen a partir de los tipos simples ya estudiados.
Distinguimos dos categoras de estructuras de datos:
Estticas: su tamao se determina a priori, antes del comienzo de la ejecucin del programa,
y este no podr incrementarse ni disminuirse en tiempo de ejecucin. Esto implicar que
cuando se trabaje con una estructura de datos esttica cuyo tamao se desconoce en la fase de
diseo, sea necesario establecer un tamao mximo y reservar espacio en memoria para ese
mximo (con el posible desperdicio de memoria que esto pueda conllevar). Entre las
estructuras de datos estticas distinguimos arrays, cadenas de caracteres y registros.
Dinmicas: su tamao se determina en tiempo de ejecucin, reservando y liberando espacio
en memoria en el momento que interese. Esto permitir, por tanto, optimizar al mximo el
espacio de ocupacin en memoria, aunque requiere una gestin de memoria ms complicada.
Distinguimos listas, rboles y grafos.
En esta asignatura nos centraremos en las estructuras de datos estticas, adecuadas como una
primera aproximacin al manejo de estructuras de datos por ser ms sencillas de gestionar.
Una caracterstica comn a todas las estructuras de datos es la existencia de un nico
identificador que hace referencia a la misma en su conjunto. Adems, cada tipo de estructura de

46

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

datos dispone de su propio mecanismo para hacer referencia de forma independiente a los elementos
que la integran.

4.2 ARRAYS
Un array es una coleccin de elementos de un mismo tipo, donde cada elemento puede
identificarse por su posicin dentro de la estructura. Todo array posee un identificador que lo
designa y una serie de ndices que toman valores enteros y permiten diferenciar por su posicin a los
distintos elementos que lo constituyen.

4.2.1 ARRAYS UNIDIMENSIONALES


Un array unidimensional puede considerarse como una lista ordenada de valores. Lleva asociado
un nico ndice que designa la posicin de sus elementos dentro de la lista, comenzando en lenguaje
C desde 0. Debido a su similitud con el concepto matemtico de vector, los arrays unidimensionales
tambin se conocen con el nombre de vectores.
En la siguiente figura se representa grficamente un vector que representa el nmero de
habitantes (en unidades de millar) de 100 poblaciones:
habitantes

0
30

1
7

2
5

99
120

...

Para hacer referencia a cada elemento del vector, tanto en algoritmia como en C, se utiliza la
siguiente sintaxis:
identificador[ndice]
Por ejemplo, el nmero de habitantes de la tercera poblacin se designa habitantes[2] y su
contenido es igual a 5.
En algoritmia, la declaracin de estructuras de datos de tipo vector utiliza el siguiente diagrama
sintctico:
VARIABLES

identificador
de variable

valor
entero

tipo

El valor entero representa el nmero de elementos del vector y, por tanto, el rango de valores que
puede tomar el ndice (en C, desde 0 a valor entero 1, ambos inclusive).
La traduccin a C de esta declaracin se realiza segn el siguiente diagrama sintctico:
tipo

identificador
de variable

valor
entero

47

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

Por ejemplo, las declaraciones del vector habitantes en algoritmia y en C emplearan la


siguiente sintaxis:
En algoritmia:

En C:

VARIABLES
habitantes[100]:entero

int habitantes[100];

En C, los conceptos de vector y puntero estn relacionados. Concretamente, el identificador de


un vector, sin especificar el ndice, representa la direccin de memoria donde comienza el vector (es
decir, la direccin del primer elemento del vector). As, en el ejemplo anterior, habitantes
representa la direccin de memoria donde se almacena habitantes[0] y, por tanto,
habitantes==&habitantes[0]
o, expresado de otro modo
*habitantes==habitantes[0]==30
Es ms, cuando un puntero p apunta a un elemento de un vector, puede utilizarse la sintaxis p+n
(donde n es un entero) para apuntar al elemento situado n posiciones a continuacin de la apuntada
por p. Por ejemplo, dado que habitantes es un puntero que apunta al primer elemento del vector
habitantes, habitantes+2 equivale a la direccin del tercer elemento del vector habitantes. As,
habitantes+2==&habitantes[2]
o, expresado de otro modo
*(habitantes+2)==habitantes[2]==5
EJEMPLO 4.1. A partir de las edades de 100 individuos introducidas por teclado, calcular y mostrar cuntos son
mayores y cuntos menores que la media.
ANLISIS:
a) Datos de entrada:
NUMIND=100. Nmero de individuos. Dato fijo.
edad[NUMIND]: Edades de los individuos. Teclado. (edad[i] 0, i)
b) Datos de salida:
may: Nmero de individuos con edad superior a la media de edad[NUMIND]. Monitor.
men: Nmero de individuos con edad inferior a la media de edad[NUMIND]. Monitor.
c) Comentarios:
Dado que, una vez calculada la media de las edades, ser necesario recorrer de nuevo la lista de edades, se
utilizar un vector para representar dicha lista.
Se utilizar una variable ndice para recorrer el vector, en primer lugar, para almacenar los valores en l
durante la lectura desde teclado y el clculo de la media y, en segundo lugar, para determinar cuntos de
esos valores son mayores y cuntos menores que la media.
Se utilizar una variable para acumular los valores del vector durante el clculo de la media.
Se utilizar una variable para almacenar el resultado de la media.
DISEO:
a) Parte declarativa:
CONSTANTES
NUMIND=100
VARIABLES
edad[NUMIND]:entero
med:real
i,suma,may,men:entero

48

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

b) Representacin algortmica:
contar
BLOCK
suma0

for do medsuma/NUMIND men0 may0 for do


BLOCK

i 0,NUMIND-1,1

escribir
leer
("Edad",i+1) (edad[i])

while do

edad[i] < 0
escribir
("Error")

if then else

i 0,NUMIND-1,1

sumasuma+edad[i]

edad[i] < med

BLOCK

escribir
(may,men)

menmen+1

edad[i] > med

if then

maymay+1

escribir
leer
("Edad",i+1) (edad[i])

CODIFICACIN:
/*************************/
/***
E D A D E S
***/
/*************************/
#include <stdio.h>
#define NUMIND 10
/* Nmero de individuos (edades) */
int main()
{
int edad[NUMIND];
double med;
int i,suma,may,men;
/* Lectura desde teclado del vector y clculo de la media */
suma=0;
for (i=0; i <= NUMIND-1; i=i+1)
{
printf("Edad %d: ",i+1);
scanf("%d",&edad[i]);
while (edad[i] < 0)
{
printf("Error, debe ser mayor o igual que cero.\n");
printf("Edad %d: ",i+1);
scanf("%d",&edad[i]);
}
suma=suma+edad[i];
}
med=suma/NUMIND;
/* Clculo de nmero de valores superiores e inferiores a la media */
men=0;
may=0;
for (i=0; i <= NUMIND-1; i=i+1)
if (edad[i] < med)
men=men+1;
else
if (edad[i] > med)
may=may+1;
/* Visualizacin de resultados */
printf("Nmero de individuos mayores que la media: %d.\n",may);
printf("Nmero de individuos menores que la media: %d.\n",men);
return 0;

49

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

4.2.2 ARRAYS MULTIDIMENSIONALES


A veces, existen datos cuya representacin es ms adecuada en forma de tabla con dos o ms
ndices, por ejemplo, para tratar la disposicin de las fichas en un tablero de ajedrez (88 casillas) o
valores diarios durante los meses de una dcada (311210 valores). Para ello, se pueden emplear
arrays multidimensionales.
Un array bidimensional (tambin denominado matriz) puede considerarse como un array
unidimensional cuyos elementos son vectores. As, por ejemplo, la representacin del censo de
habitantes de 100 poblaciones en las 3 ltimas dcadas podra efectuarse mediante una matriz de
dimensiones 1003, como se muestra en la siguiente figura:
ndice de dcada
0
1
2
31
28
30
10
8
7
...
...
...
60
90
120

habitantes
ndice de
poblacin

0
1
...
99

Para referenciar a cada elemento de un array bidimensional se utilizan dos ndices. El primero se
refiere a la fila y el segundo a la columna que ocupa dicho elemento. Se utiliza la siguiente sintaxis:
identificador[fila][columna]
Por ejemplo, el nmero de habitantes de la segunda poblacin en el censo de la primera dcada
se designa habitantes[1][0] y su contenido es igual a 10.
Anlogamente, pueden declararse arrays de tantas dimensiones como se quiera, teniendo como
nica limitacin el tamao de la memoria del ordenador. El nmero total de elementos del array es
el producto del nmero de elementos de cada dimensin. Por ejemplo, un array de dimensin
3102 tendr 60 elementos. No obstante, obsrvese que a mayor nmero de dimensiones, menor
ser la legibilidad de la solucin y mayor la dificultad de su manejo, pues cada ndice har
referencia a una caracterstica de los datos y debemos saber en qu orden debe situarse cada uno de
los ndices (por ejemplo, primero el cdigo de poblacin, a continuacin la dcada, etc.).
En general, un elemento de un array n-dimensional se referencia con la siguiente sintaxis:
identificador[ndice1][ndice2]...[ndicen]
Al igual que en el caso de los vectores, todos los elementos de un array multidimensional deben
ser de igual tipo. Si junto con el nmero de habitantes del ejemplo anterior quisiramos almacenar
el nombre de la entidad que realiz el censo (representado por un dato de tipo cadena de caracteres),
sera preciso declarar una nueva matriz de tamao 1003 en vez de aadir una nueva dimensin al
array original, ya que los datos a almacenar son de distinto tipo.
En algoritmia, la declaracin de una estructura de datos array multidimensional utiliza el
siguiente diagrama sintctico:
VARIABLES

identificador
de variable

valor
entero

tipo

Ahora, cada valor entero representa el nmero de elementos de la dimensin correspondiente y,


por tanto, el rango de valores que puede tomar su ndice (en C, desde 0 a valor entero 1).
50

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

La traduccin a C de esta declaracin se realiza segn el siguiente diagrama sintctico:


tipo

identificador
de variable

valor
entero

,
Por ejemplo, la declaracin de la matriz habitantes vista anteriormente empleara la
siguiente sintaxis:
En algoritmia:

En C:
int habitantes[100][3];

VARIABLES
habitantes[100][3]:entero

EJEMPLO 4.2. Almacenar desde teclado una matriz de reales de dimensiones 20x20 por filas y mostrar por pantalla
la suma de sus columnas.
ANLISIS:
a) Datos de entrada:
NUMFIL=20. Nmero de filas. Dato fijo.
NUMCOL=20. Nmero de columnas. Dato fijo.
m[NUMFIL][NUMCOL]: Matriz de nmeros reales. Teclado.
b) Datos de salida:
s[NUMCOL]: Sumas de las columnas de la matriz. Monitor.
c) Comentarios:
Se utilizarn dos variables ndice para recorrer la matriz, en primer lugar, durante su lectura desde teclado y,
en segundo, durante el clculo de la suma de cada columna.
Dado que se mostrar la suma de cada columna tras su clculo, no es necesario recordar simultneamente
cada una de ellas, por lo que slo se utilizar una variable para almacenarlas.
DISEO:
a) Parte declarativa:
CONSTANTES
NUMFIL=20
NUMCOL=20
VARIABLES
m[NUMFIL][NUMCOL]:real
i,j:entero
s:real
b) Representacin algortmica:
sumaColumnas
BLOCK
for do
i0,NUMFIL-1,1

for do

BLOCK

escribir("Fila",i+1)
j0,NUMCOL-1,1

BLOCK

j0,NUMCOL-1,1

for do
leer(m[i][j])

s0
i0,NUMFIL-1,1

for do

escribir(s)

ss+m[i][j]

51

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

CODIFICACIN:
/***************************************/
/***
S U M A
C O L U M N A S
***/
/***************************************/
#include <stdio.h>
#define NUMFIL 5
/* Nmero de filas de la matriz */
#define NUMCOL 5
/* Nmero de columnas de la matriz */
int main()
{
double m[NUMFIL][NUMCOL],s;
int i,j;
/* Lectura desde teclado de la matriz por filas */
for (i=0; i <= NUMFIL-1; i=i+1)
{
printf("Fila %d: ",i+1);
for (j=0; j <= NUMCOL-1; j=j+1)
scanf("%lf",&m[i][j]);
}
/* Clculo de la suma de cada columna y visualizacin de resultados */
for (j=0; j <= NUMCOL-1; j=j+1)
{
s=0;
for (i=0; i <= NUMFIL-1; i=i+1)
s=s+m[i][j];
printf("La suma de la columna %d es %.2f.\n",j+1,s);
}
return 0;

4.3 CADENAS DE CARACTERES


En el desarrollo de programas, a menudo es necesario tratar informacin alfabtica, por ejemplo,
para la creacin y gestin de listas de personal, inventarios, etc. El tipo de datos utilizado para
representar esta informacin se denomina cadena de caracteres o, simplemente, cadena.
Se llama longitud de una cadena al nmero de caracteres que contiene. La cadena que no
contiene ningn carcter se denomina cadena vaca o nula y su longitud es cero.
Para declarar en C una variable de tipo cadena con una longitud mxima de 14 caracteres
significativos utilizaremos la siguiente sintaxis:
char cadena[15];
donde el ltimo elemento del vector se reserva para el carcter especial '\0' (carcter nulo) que
representa el fin de la cadena.

52

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

4.3.1 OPERACIONES CON CADENAS


Una cadena de caracteres no es ms que un vector de caracteres delimitado por el carcter nulo.
Por ello, en la mayora de los casos, podemos operar con las cadenas del mismo modo que con
cualquier otro vector. No obstante, existe una biblioteca de funciones en C (con archivo de cabecera
string.h) que permiten manejar las cadenas de caracteres de un modo ms cmodo. En esta
seccin estudiaremos algunas de ellas.

ASIGNACIN
Al igual que con cualquier otro vector, para almacenar en una variable de tipo cadena una cadena
de caracteres, el uso del operador de asignacin requerira asignar uno a uno los caracteres que
componen la cadena al elemento correspondiente de la variable mediante el uso de una estructura
repetitiva for do. En lugar de ello, puede realizarse la misma asignacin ms cmodamente
utilizando la funcin interna strcpy. Esta funcin emplea dos parmetros: el primero, la variable
cadena que recibir la asignacin, y el segundo, la cadena a asignar.
Por ejemplo, dada la variable cadena declarada en la seccin anterior, la instruccin de C
strcpy(cadena,"1234567890"); almacenar en dicha variable el valor "1234567890".
La funcin strcpy copia todos los caracteres contenidos en el segundo parmetro hasta
encontrar el carcter nulo. Por ello, el programador debe asegurarse de reservar suficiente espacio
durante la declaracin de la variable que va a albergar el contenido que se le asigna. Por ejemplo, la
instruccin strcpy(cadena,"123456789012345"); no sera correcta, ya que se estn
intentando asignar 16 caracteres (15 significativos ms el carcter nulo) a una cadena para la que
solo se han reservado 15.
En algoritmia, nos referiremos a esta operacin con el operador de asignacin .

LECTURA Y ESCRITURA
Aunque una cadena de caracteres es un vector de caracteres y podemos hacer referencia a sus
caracteres individuales utilizando la notacin de vectores, a diferencia de otros tipos de vectores,
para leer por teclado o escribir en pantalla una cadena de caracteres basta con incluir el nombre de la
variable entre los parntesis de una instruccin gets o printf, respectivamente, tal y como se
estudi en el Captulo 3.

COMPARACIN
La comparacin de cadenas posee gran importancia en la ordenacin de datos alfabticos,
bsqueda de textos, etc. El criterio de clasificacin se basa en el orden numrico de los caracteres
segn su cdigo de ASCII.
Dos cadenas sern iguales si contienen exactamente los mismos caracteres situados en el mismo
orden. En otro caso, el resultado de la comparacin ser el del primer par de caracteres distintos
situados en una misma posicin. En este sentido, la presencia de cualquier carcter se considerar
siempre mayor que la ausencia de carcter.

53

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

En C, para comprobar si dos cadenas son iguales se utilizar la funcin interna strcmp, que
tiene como parmetros las dos cadenas de caracteres a comparar. El valor devuelto por la funcin
tiene el siguiente significado:
Un valor positivo significa que la primera cadena es mayor (sucede alfabticamente) a la
segunda.
Un valor igual a cero significa que ambas cadenas son idnticas.
Un valor negativo significa que la primera cadena es menor (precede alfabticamente) a la
segunda.
Ejemplos de comparaciones son:
strcmp("norte","norte")
strcmp("ciber","ciudad")
strcmp("DATOS ","DATOS")
strcmp("lima","Lima")
strcmp("casa","casaca")

0
negativo
positivo
positivo
negativo

En algoritmia, representaremos las comparaciones entre cadenas mediante los operadores


relacionales (=, , , , >, <).

CLCULO DE LA LONGITUD
Para calcular la longitud de una cadena en lenguaje C se utiliza la funcin interna strlen.
Como parmetro se especificar un valor de tipo cadena. Devolver un valor entero igual a la
longitud actual de la cadena (sin contar el carcter nulo). En algoritmia nos referiremos a esta
operacin con la palabra longitud.

CONCATENACIN
La concatenacin consiste en la unin de varias subcadenas en una nica cadena. En algoritmia,
utilizaremos el operador de suma (+) para representar la concatenacin. Por ejemplo,
"PARA"+"BRISAS" = "PARABRISAS"
Puede observarse que se unen las cadenas sin insertar espacios en blanco entre ellas, por lo que
estos debern incluirse explcitamente en alguna de las cadenas a concatenar si se desea que
permanezcan separadas.
En lenguaje C, la concatenacin se consigue mediante la funcin interna strcat, que aade una
cadena al final de otra cadena. Utiliza dos parmetros: el primero, la variable cadena destino de la
concatenacin, y el segundo, la cadena que se aade.
Por ejemplo, dada la variable cadena de secciones anteriores, tras las siguientes dos
instrucciones:
strcpy(cadena,"PARA");
strcat(cadena,"BRISAS");

la variable cadena contendr el valor "PARABRISAS".

54

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

BSQUEDA
La operacin de bsqueda consiste en localizar una determinada cadena como parte de otra
cadena ms grande. En C, la funcin que realiza este cometido es strstr, que utiliza dos
parmetros de tipo cadena: el primero, la cadena donde se buscar; el segundo, la subcadena a
localizar. El valor devuelto es un puntero a la subcadena buscada en la primera aparicin dentro de
la cadena explorada. Si la subcadena no aparece en la cadena, el valor devuelto ser NULL. En la
representacin algortmica se utilizar la palabra buscar.
Por ejemplo, dada la cadena cadena="En un lugar de la Mancha de..."
strstr(cadena,"de")

En un lugar de la Mancha de...


^

strstr(cadena,"e")

En un lugar de la Mancha de...


^

strstr(cadena,"arde")

devuelve el valor NULL

EJEMPLO 4.3. Desarrollar un programa que lea dos cadenas de mximo 100 caracteres y muestre el nmero de
veces que la segunda aparece incluida en la primera, sin contabilizar solapamientos.
ANLISIS:
a) Datos de entrada:
LONMAX=100: Longitud mxima de las cadenas. Dato fijo.
cad[LONMAX+1]: Cadena a examinar. Teclado
sub[LONMAX+1]: Subcadena a buscar. Teclado
b) Datos de salida:
rep: Nmero de veces que la subcadena sub aparece en la cadena cad (sin solapamientos). Monitor.
c) Comentarios:
Se emplear una variable para contar el nmero de ocurrencias de la subcadena en la cadena.
Debido a que la funcin strstr slo busca la primera ocurrencia de una subcadena, habr que ir
desechando la parte de la cadena ya inspeccionada. Por ello, se utilizar un puntero que apunte a cada
ocurrencia de la subcadena, lo que nos permitir determinar qu parte de la cadena queda por explorar.
DISEO:
a) Parte declarativa:
CONSTANTES
LONMAX=100
VARIABLES
cad[LONMAX+1],sub[LONMAX+1],*p:carcter
rep:entero
b) Representacin algortmica:
repeticiones
BLOCK
escribir
leer
rep0
("Cadenas:") (cad,sub)

pbuscar(cad,sub)
p NULL

while do

escribir(rep)

BLOCK

reprep+1 cadp+longitud(sub)

pbuscar(cad,sub)

55

4. ESTRUCTURAS DE DATOS (I): ARRAYS. CADENAS DE CARACTERES

CODIFICACIN:
/***************************************/
/***
R E P E T I C I O N E S
***/
/***************************************/
#include <stdio.h>
#include <string.h>
#define LONMAX 100
/* Longitud mxima de las cadenas */
int main()
{
char cad[LONMAX+1],sub[LONMAX+1],*p;
int rep;
printf("Introduce la cadena a inspeccionar: ");
fflush(stdin); gets(cad);
printf("Introduce la subcadena a buscar: ");
fflush(stdin); gets(sub);
rep=0;
p=strstr(cad,sub);
while (p != NULL)
/* Mientras se encuentre sub en cad */
{
rep=rep+1;
strcpy(cad,p+strlen(sub));
p=strstr(cad,sub);
}
printf("La subcadena aparece %d veces en la cadena\n",rep);
return 0;

56