Вы находитесь на странице: 1из 5

5.

El problema de la transformacin de una cadena en otra


Dadas dos cadenas de caracteres u y v se desea tranformar u en v, usando el mnimo
nmero de operaciones.
Las operaciones permitidas son:
a) borrar un carcter
b) insertar un carcter
c) sustituir un carcter
Solucin
U

V
m elementos

n elementos

Si u[m-1] = v[n-1]
Si las ltimas letras son iguales, entonces no necesitamos hacer ninguna operacin por lo
que el numero de operaciones sera igual al numero de operaciones que hicimos antes de
considerar esa ultima letra, esto es nroOp(m-1,n-1).
Si u[m-1] v[n-1]
a) Puede ser que la primera cadena sea mas pequea que la segunda por lo que le faltara esa
ultima letra, esto es m<n (esto es m+1=n), como nos hace falta el carcter debemos insertar
un elemento al final de u que sea igual al ultimo elemento de v. Osea debemos insertar en
u[m-1] un elemento igual a v[m-1].
Como se inserto entonces es una operacin mas. Despus de insertar el elemento, las dos
cadenas tienen ese elemento iguales. Por lo que tendremos que calcular cuantas operaciones
tienen que hacerse cuando dejemos de considerar ambos elementos. Como u tenia m
elementos y v tenia n, entonces a u le habiamos aadido un elemento entonces nos
quedaran los mismos m elementos diferentes, mientras que en v, como al insertar el
elemento en v, ya emparejamos el ultim elemento, nos quedaran n-1 elementos por
emparejar. Asi que: 1 + nroOp(m, n-1)
b) Puede ser que la primera cadena u, sea mas grande que la segunda (m>n), por lo cual
borramos ese carcter (1 operacin), y debemos encontrar el nroOp considerando ese
elemento borrado u tendra m-1 caracteres y v tendria n. Osea tendriamos 1+nroOp(m-1,n)
c) si las longitudes de ambas cadenas son las mismas, entonces debemos sustituir el
carcter u[m-1] por el carcter v[n-1], lo cual seria una operacin mas. Esto es, nos
quedaran por encontrar el numero de operaciones para u y v cuando no consideramos el
ultimo elemento en ambas. Esto es: 1 + nroOp(m-1, n-1)

# include <iostream.h>
# include <string.h>
#define MAX 100
void impTabla(int f, int c, int t[][MAX]);
void transformaCad(char u[],char v[], int n, int m);
int Min(int a, int b, int c);
int T[MAX][MAX];
void main(void)
{
char u[MAX], v[MAX];
int m,n;
cout<<"ingrese primera cadena: "; cin>>u;
cout<<"ingrese segunda cadena: "; cin>>v;
m=strlen(u);
n=strlen(v);
transformaCad(u,v, n, m);
impTabla(m+1, n+1, T);
}
void transformaCad(char u[],char v[], int n, int m)
{
int i, j;
for(i=0; i<=m; i++)
T[i][0]=i;
for(j=0; j<=n; j++)
T[0][j]=j;
for(i=1; i<=m; i++)
for(j=1; j<=n; j++)
if(u[i-1]==v[j-1])
T[i][j]=T[i-1][j-1];
else
T[i][j]=1 + Min( T[i][j-1], T[i-1][j-1], T[i-1][j]);
}
int Min(int a, int b, int c)
{
int min=a;
if ( min> b ) min= b;
if ( min> c ) min= c;
return min;
}
void impTabla(int f, int c, int t[][MAX])
{
for(int i=0; i<f; i++)
{
for(int j=0; j< c; j++)
cout<<t[i][j]<<" ";
cout<<endl;
}
}

Aplicaciones:
Se tienen varias versiones parecidas de un fichero, obviamente es mucho mas eficiente
almacenar solo la primera version y el resot de versiones almacenar los pasos de edicion
que son inserciones y eliminacin. Eso se aplica en los sof de control de versiones como el
visual sourcefage Word, etc.
Si fuera planteado recursivamente el caso base seria
nroOp(i, j)

si i=j entonces nroOP(i,j)=0


sino
si u[i]=v[j]
1+nroOp(i, j)

nroOp(m-1,n-1).
1 + nroOp(m, n-1)
1 + nroOp(m-1, n-1)
(corregir eso...)
Se complejidad de la formulacion recursiva es exponencial, y se observa q se trata de
problemas superpuestos, pero solo existen mn soluciones
Se observa que se cumple el principio de optimalidad puesto que cada operacion de los
elementos m y n, se basan en los optimos de los m-1 n-1.
abbac
abcbc

u= abc

v = baca
Por ejemplo, transformar u=ABC hacia v=BACA, m son las

A
B
C

1
2
3

0
1
2
3

1
1
1
2

2
1
2
2

3
2
2
2

4
3
3
3

nroOP(0, 0 ), nroOP(0, 1 ), nroOP(0, 2 ), nroOP(0, 3 ), nroOP(0, 4 )


Consideremos que la cadena u es vacia, y queremos convertirla a la cadena v tambin
vacia, entonces haremos 1 operacin. nroOP(0, 0 ) = 0
Si la cadena u esta vaca para convertirla en v=B, necesitamos 1 operacin.
Si la cadena u esta vaca y la queremos convertir a v=BA, serian 2 operaciones.
Si la cadena u esta vaca y la queremos convertir a v=BAC, serian 3 operaciones.
Si la cadena u esta vaca y la queremos convertir a v=BACA, serian 4 operaciones.
nroOP(1, 0 ), nroOP(2, 0 ), nroOP(3, 0 )
Si la cadena u=A para convertirla en v vaca, necesitamos 1 operacin.
Si la cadena u=AB y la queremos convertir a v vaca, necesitamos 2 operaciones.
Si la cadena u=ABC y la queremos convertir a v vaca, necesitamos 3 operaciones.

A
B
C

1
2
3

0
1
2
3

nroOP(1, 1 ): Costo para convertir A en B


Si tenemos u=A para convertirla en B, tenemos que tomar el mnimo de
Cambiar a A en vaco ms agregar B. nroOP(1,0) + 1 = 1+1=2
Remplazar A por B
nroOP(0,0) + 1 = 0+1=1
Eliminar A, mas agregar B
nroOP(0,1) + 1 = 1+1=2
nroOP(1,0)=1

A
B
C

1
2
3

0
1
2
3

1
1

nroOP(1, 2 ): Costo para convertir A en BA


como el ultimo termino de ambos es el mismo entonces solo hay q agregar B, osea
nroOP(1,2)=1

A
B
C

1
2
3

0
1
2
3

1
1

2
1

nroOP(1, 3 ): Costo para convertir A en BAC


sera el minimo de:
haber convertido A en BA (op[1][2]). Mas agregar C: 1+1
eliminar A, luego agregar B, agregar A, mas agregar C = 3
haber convertido A en BA (op[1][2]) y luego agregar C
(revisar)

Вам также может понравиться