Professional Documents
Culture Documents
Apellidos y nombre:
Profesor: 2 Joan Andreu Sanchez 2 David Pico 2 Enrique Vidal
Tiempo: 3 horas
1. (1 punto)
Se desea implementar una funcion que tome como argumento una cadena de caracteres y muestre
por la salida estandar todas las rotaciones posibles de la cadena. Por ejemplo, si la cadena de entrada
es abcdefg la salida ha de ser:
abcdefg
bcdefga
cdefgab
defgabc
efgabcd
fgabcde
gabcdef
tam=strlen(cad);
printf("%s\n",cad) /* -> */ ; /* <- */
for (i=1;i<tam;i++) /* -> */ { /* <- */
/* Imprimir desde i hasta el final... */
for (j=i;j<tam;j++)
printf("%c",cad[j]);
/* Imprimir desde 0 hasta i-1 */
for (j=0;j<i;j++)
printf("%c",cad[j]);
printf("\n");
/* -> */ } /* <- */
}
Por simplicidad, se puede suponer que ninguna vocal, mayuscula o minuscula, va a estar acentuada.
El uso de la funcion ha de ser similar al del siguiente ejemplo:
b) Implementa una funcion que lea un texto de un fichero y lo escriba en otro suprimiendo las vocales.
El perfil de la funcion debe ser el siguiente1 :
Los argumentos son los nombres de los ficheros de entrada y salida (dos cadenas de texto). Para
simplificar se puede suponer que el fichero de entrada contiene solo una palabra por lnea. Puede
usarse la funcion definida en el apartado anterior.
Solucion:
a) /* Se define la macro ES_VOCAL, para decidir si una letra es vocal o no */
if ((fin=fopen(entrada,"r"))==NULL) {
printf("Error al abrir %s",entrada);
return;
}
if ((fout=fopen(salida,"w"))==NULL) {
printf("Error al abrir %s",salida);
return;
}
while (fscanf(fin,"%s",buffer)>0) {
borra_vocales(buffer);
fprintf(fout,"%s\n",buffer);
}
fclose(fin);
fclose(fout);
}
3. (3 puntos)
Se dispone de las siguientes definiciones de estructuras que representan, respectivamente, las coor-
denadas de un punto en 2 y 3 dimensiones.
a) Escribe una funcion que tome como argumento una variable de tipo punt2D que represente al punto
(x, y), calcule una tercera coordenada como z = x2 + y 2 y retorne el punto (x, y, z), representado
como elemento de estructura punt3D.
b) Escribe una funcion que tome como argumentos dos variables de tipo punt2D y retorne la distancia
Eucldea entre ellos. La distancia Eucldea entre dos puntos p = (x1 , y1 ) y q = (x2 , y2 ) se calcula
como p
d(p, q) = (x1 x2 )2 + (y1 y2 )2
Para el calculo de la raz cuadrada puede usarse la funcion sqrt: float sqrt(float x).
c) Implementa una funcion F que tome como argumentos dos variables de tipo punt2D, p y q, y
retorne 1 si p esta mas proximo del origen de coordenadas z = (0, 0) que q, -1 si q esta mas proximo
que p, y 0 si estan a la misma distancia, es decir:
+1 si d(p, z) < d(q, z)
F (p, q) = 0 si d(p, z) = d(q, z)
1 si d(p, z) > d(q, z)
punt3D terceraCoordenada(punt2D a) {
punt3D aux;
aux.x = a.x;
aux.y = a.y;
aux.z = a.x * a.x + a.y * a.y;
return aux;
}
dp=Euclidea(origen, p);
dq=Euclidea(origen, q);
if (dp<dq) return 1;
else if (dp>dq) return -1;
else return 0;
}
4. (1 puntos)
Considera la funcion f incluida a continuacion:
#define N ...
...
void f(int m[N][N], int v[N], int r[N]) {
int i,j;
a) Discute que parametro es adecuado para medir la talla del problema resuelto por f.
b) Estudia la complejidad temporal correspondiente.
c) Que calcula la funcion f?
Solucion:
a) El coste temporal de f depende esencialmente del numero de iteraciones de los bucles en i y en j;
es decir de N. Por tanto N es un parametro adecuado para medir la talla del problema resuelto por f.
b) La operacion del bucle mas interno (r[i] = r[i] + m[i][j]*v[j]) tiene un coste unitario;
es decir, independiente de N , y se ejecuta exactamente N 2 veces. Lo mismo puede decirse de las
operaciones de incremento del ndice y control del bucle for (j=...). La operacion r[i] = 0,
as como las operaciones de incremento del ndice y control del bucle for (j=...), tienen tambien
costes unitarios y se ejecutan exactamente N veces. Ademas hay costes unitarios como por ejemplo
la inicializacion i=0 del bucle externo.
Por tanto, el coste temporal lo podemos expresar como T (N ) = N 2 + N + 1 (N 2 )
c) La funcion f realiza el siguiente calculo matricial:
N
X 1
r = m v; ri = mij vj , v i < N
j=0
tx=strlen(x); ty=strlen(y);
for (i=0; i<ty-tx+1; i++) {
j=0;
while ((j<tx) && (x[j]==y[i+j])) j++;
if (j==tx) return(1);
}
return(0);
}
a) Discute que parametro es adecuado para medir la talla del problema resuelto por subcad.
b) Determina que tipos de cadenas y son casos mejor y peor para el coste temporal de subcad.
c) Estudia la complejidad temporal asintotica de subcad.
Solucion:
a) El coste de subcad depende del numero de iteraciones del bucle for, el cual depende basicamente
de la longitud de la cadena y (ya que la longitud de x es constante). Llamaremos n a la longitud
de y.
b) Las instancias (y) mas favorables seran aquellas para las que el bucle for termine cuanto antes
por la condicion if (j==tx) return(1). Esta condicion se cumple cuando el while realiza todas
las iteraciones con (x[j]==y[i+j]; es decir cuando la cadena completa x coincide con la subca-
dena y[i] y[i+tx-1]. El menor valor de i para el que se puede dar esta coincidencia es i=0.
Resumiendo, el mejor caso se da cuando y es de la forma aab .
Por el contrario, el peor caso se da cuando el bucle for realiza el maximo numero m de iteraciones;
es decir, m = ty-tx+1 = ntx+1. Este caso corresponde a instancias y en las que no hay ninguna
subcadena de y que coincida con x; es decir, instancias para las que subcad(x)= 0.
c) En el mejor caso, la funcion f realiza solo un pequeno numero de iteraciones c (c = 3) de su bucle
while. Este numero no depende de n, por lo que el coste es unitario. En el peor caso se realizan n c
iteraciones del bucle for y, en cada iteracion, el bucle while itera como maximo c 1 veces, por lo
que el coste sera como maximo (c 1)n c2 + c pasos. Como c no depende de n, podemos resumir
la complejidad temporal de la funcion subcad como: T (n) (1), T (n) O(n).
1
Notese que si X es un vector, en la definicion de una funcion la notacion X[] es equivalente a * X.