codigo c++

7
5. El problema de la transformación de una cadena en otra Dadas dos cadenas de caracteres u y v se desea tranformar u en v, usando el mínimo número de operaciones. Las operaciones permitidas son: a) borrar un carácter b) insertar un carácter c) sustituir un carácter Solución U V m elementos n elementos Si u[m-1] = v[n-1] Si las últimas letras son iguales, entonces no necesitamos hacer ninguna operación por lo que el numero de operaciones sería 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 pequeña 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 carácter 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 operación mas. Después 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,

Upload: victor-palacios

Post on 31-Jan-2016

212 views

Category:

Documents


0 download

DESCRIPTION

El problema de la transformación de una cadena en otra

TRANSCRIPT

Page 1: codigo c++

5. El problema de la transformación de una cadena en otra

Dadas dos cadenas de caracteres u y v se desea tranformar u en v, usando el mínimo número de operaciones. Las operaciones permitidas son:

a) borrar un carácterb) insertar un carácterc) sustituir un carácter

Solución

U V

m elementos n elementos

Si u[m-1] = v[n-1]

Si las últimas letras son iguales, entonces no necesitamos hacer ninguna operación por lo que el numero de operaciones sería 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 pequeña 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 carácter 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 operación mas. Después 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 añadido 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 carácter (1 operación), y debemos encontrar el nroOp considerando ese elemento borrado u tendría 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 carácter u[m-1] por el carácter v[n-1], lo cual seria una operación mas. Esto es, nos quedarían 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)

Page 2: codigo c++

# include <iostream.h># include <string.h>#define MAX 100void 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];

elseT[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++){

Page 3: codigo c++

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 eliminación. Eso se aplica en los sofá de control de versiones como el visual sourcefage Word, etc.

Si fuera planteado recursivamente el caso base seria

si i=j entonces nroOP(i,j)=0nroOp(i, j) 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 solucionesSe 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.

abbacabcbc

u= abc

# include <iostream.h># include <string.h>#define MAX 100void 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];

elseT[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++){

Page 4: codigo c++

v = baca

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

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 también vacia, entonces haremos 1 operación. nroOP(0, 0 ) = 0

Si la cadena u esta vacía para convertirla en v=B, necesitamos 1 operación. Si la cadena u esta vacía y la queremos convertir a v=BA, serian 2 operaciones.Si la cadena u esta vacía y la queremos convertir a v=BAC, serian 3 operaciones.Si la cadena u esta vacía 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 vacía, necesitamos 1 operación.Si la cadena u=AB y la queremos convertir a v vacía, necesitamos 2 operaciones.Si la cadena u=ABC y la queremos convertir a v vacía, necesitamos 3 operaciones.

nroOP(1, 1 ): Costo para convertir A en BSi tenemos u=A para convertirla en B, tenemos que tomar el mínimo deCambiar a A en vacío más agregar B. nroOP(1,0) + 1 = 1+1=2Remplazar A por B nroOP(0,0) + 1 = 0+1=1Eliminar A, mas agregar B nroOP(0,1) + 1 = 1+1=2nroOP(1,0)=1

0B1

A2

C3

A4

0 0 1 2 3 4A 1 1 1 1 2 3B 2 2 1 2 2 3C 3 3 2 2 2 3

0B1

A2

C3

A4

0 0 1 2 3 4A 1 1B 2 2C 3 3

0B1

A2

C3

A4

0 0 1 2 3 4A 1 1 1B 2 2C 3 3

Page 5: codigo c++

nroOP(1, 2 ): Costo para convertir A en BAcomo el ultimo termino de ambos es el mismo entonces solo hay q agregar B, osea nroOP(1,2)=1

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

(revisar)

0B1

A2

C3

A4

0 0 1 2 3 4A 1 1 1 1B 2 2C 3 3