sexta-feira, 3 de abril de 2020


Hoje irei disponibilizar um código em advpl para verificar a similaridade de duas strings. Ele é uma adaptação que eu fiz baseado no algorítimo de Levenshtein.
Mais detalhes no link :Levenshtein distance
Basicamente ele informa quantos operações serão necessárias para deixar uma string igual a outra. Algo muito utilizado em corretores ortográficos como também em aplicações de IA em que podemos analisar a resposta dada por algum usuário em um questionário ou um Chatbot.


Por exemplo, a distância Levenshtein entre as palavras inglesas "kitten" (gato) e "sitting" (sentando-se) é 3, já que com apenas 3 edições conseguimos transformar uma palavra na outra, e não há maneira de o fazer com menos de três edições:
  • kitten
  • sitten (substituição de 'k' por 's')
  • sittin (substituição de 'e' por 'i')
  • sitting (inserção de 'g' no final)


Segue o fonte:
#INCLUDE "PROTHEUS.CH" 
#INCLUDE "RWMAKE.CH" 
#include 'tbiconn.ch'

//recebe duas strings como parâmetro e realiza a comparação entre elas usando
//o algorítimo de Levenshtein

User Function POSTRING(s,t)
Local i := 1
Local j := 1
Local sa   := {}
Local ta   := {}

//transformar string em array 
for i := 1 To len(s)
    aaDD(sa,SubStr(s,i,1))
next 
for i := 1 To len(t)
    aaDD(ta,SubStr(t,i,1))
next 


n = Len(s
m = Len(t
d = Array(n+1,m+1)

//colocando zeros nas posições do array pois n pode ter elemento nulo (nil)
for i := 1 To n+1
    for j := 1 To m+1
        d[i,j] := 0
    next j
next i 



if (n == 0)
    return m
EndIf
if (m == 0)
    return n
Endif

for i = 1 To  n + 1 
    d[i, 1] = i-1
next

for j = 1 To m + 1
    d[1, j] = j-1
next

for i := 2 To n + 1
    for j:= 2 To m + 1
        cost = iif(ta[j - 1] == sa[i - 1],0,1)
        d[i, j] = Min(Min(d[i - 1, j] + 1, d[i, j - 1] + 1),d[i - 1, j - 1] + cost)
    next j
next i 


Return  d[n+1, m+1]