Você está na página 1de 18

Centro Universitrio Serra dos rgos

Centro de Cincias e Tecnologia


Curso de Graduao em Cincia da Computao

Distncia de Edio e LCS

1/46

Distncia de Edio

Distncia de Edio uma maneira de medir a


distncia entre duas cadeias de caracteres

Existem diversas mtricas, uma das mais


comuns a chamada de Distncia de Edio
de Levenshtein, que considera as seguintes
operaes:

Insero de Caractere
Remoo de Caractere
Substituio de Caractere

A distncia entre duas cadeias dada pela quantidade


de operaes que precisam ser executadas em uma
cadeia para que ela fique exatamente igual a outra 2/46

Distncia de Edio

Exemplo, cadeias kitten e sitting


1 - kitten sitten (trocar o "s" por "k")
2 - sitten sittin (trocar o i" por e")
3 - sittin sitting (inserir o "g" ao final)
Supondo que as trs operaes tm o mesmo custo, a
distncia de edio neste caso igual a 3.

3/46

Distncia de Edio

Exemplo, cadeias kitten e sitting


1 - kitten sitten (trocar o "s" por "k")
2 - sitten sittin (trocar o i" por e")
3 - sittin sitting (inserir o "g" ao final)
Supondo que as trs operaes tm o mesmo custo, a
distncia de edio neste caso igual a 3.
No h como transformar uma cadeia em outra com
menos operaes
4/46

Distncia de Edio

Matematicamente a Distncia de edio


dada pela seguinte frmula:
Sejam duas cadeias S e T. E sejam Si e Tj prefixos de
tamanhos i e j de S e T respectivamente. A distncia de
edio entre S e T (Lev(S, T)) dada por:

5/46

Distncia de Edio

Verso Recursiva (Ineficiente)


int leverstein(char * S, char * T, int i, int j)
{

if(i == 0)
return j;

if(j == 0)
return i;

int mesmo_char = !(S[i] == T[j]);

6/46

Distncia de Edio

Usando DP
int leversteinDP(char * S, char * T, int s, int t)
{
int custos[s+1][t+i];
for(int i = 0; i < s; i++) custos[i][0] = i;
for(int i = 0; i < t; i++) custos[0][i] = i;

for(int i = 1; i <= s; i++)


{
for(int j = 1; j <= t; j++)
{
int mesmo_char = !(S[i-1] == T[j-1]);
int custo_remocao = leverstein[i-1][j] + 1;
int custo_adicao = leverstein[i][j-1] + 1;

7/46

Distncia de Edio

s
i
t
t
i
n
g

Exemplo: Sitting x Kittien

0
1
2
3
4
5
6
7

k
1
1
2
3
4
5
6
7

i
2
2
1
2
3
4
5
6

t
3
3
2
1
2
3
4
5

t
4
4
3
2
1
2
3
4

e
5
5
4
3
2
2
3
4

n
6
6
5
4
3
3
2
3
8/46

Maiores
Subcadeias e Subsequnciais

9/46

LCS

LCS (Longest Common Subsequence), maior


subsequncia comum entre duas cadeias.

Uma subsequncia uma sequncia que pode


ser derivada de outra atravs da remoo de
alguns elementos, porm sem alterar sua
ordem.

Exemplo, cadeias: AGCAT e GAC

Maiores subsequncias: AC, GC, GA


10/46

LCS

Definio Matemtica:

Sejam duas cadeias S e T. E sejam Si e Tj


prefixos de tamanhos i e j de S e T
respectivamente. A LCS entre as duas dada
por:

11/46

LCS

Podemos utilizar DP para calcular a seguinte


tabela com base na definio:

12/46

LCS

Calcular a LCS envolve armazenar vrias


subsequncias durante o clculo da tabela.
possvel poupar espao armazenando apenas
o comprimento da LCS e a seta ao invs de
todas as subsequncias

13/46

LCS

Algoritmo (usando DP) para o clculo do


tamanho da LCS

int LCS(char * S, char * T, int s, int t)


{
int tamanhos[s+1][t+i];
for(int i = 0; i < s; i++) tamanhos[i][0] = 0;
for(int i = 0; i < t; i++) tamanhos[0][i] = 0;
for(int i = 1; i <= s; i++)
{
for(int j = 1; j <= t; j++)
{
if(S[i] == T[j]) tamanhos[i][j] = tamanhos[i-1][j-1]+1;
else tamanhos[i][j] = max(tamanhos[i-1][j], tamanhos[i][j-1]);
}
}
return tamanhos[s][t];
}

14/46

LCS

LCS (Longest Common Subsequence) no deve


ser confundido com a Longest Common
Substring.

Uma substring (subcadeia) uma sequncia


de caracteres contida dentro outra,
respeitando a ordem e a vizinhana dos
caracteres.

Exemplo, cadeias: ABABC e BABCA

Maiore substring comum: ABC

15/46

LCS

Matematicamente temos a seguinte definio.


Ela similar a da LCS, s que consideramos
apenas sequncias de caracteres iguais.

Sejam duas cadeias S e T. E sejam Si e Tj


prefixos de tamanhos i e j de S e T
respectivamente. O tamanho da maior
substring comum :

16/46

LCS

Algoritmo (usando DP) para o clculo do


tamanho da LCString

int LCString(char * S, char * T, int s, int t)


{
int tamanhos[s+1][t+i];
int LCSsize = 0;
for(int i = 0; i < s; i++) tamanhos[i][0] = 0;
for(int i = 0; i < t; i++) tamanhos[0][i] = 0;
for(int i = 1; i <= s; i++)
{
for(int j = 1; j <= t; j++)
{
if(S[i] == T[j])
tamanhos[i][j] = tamanhos[i-1][j-1]+1;
else tamanhos[i][j] = 0;
if(LCSsize < tamanhos[i][j]) LCSsize = tamanhos[i][j];
}
}
return LCSsize;
}

17/46

LCS

Tabela obtida pela DP

18/46

Você também pode gostar