Busca lo que quieras

Distancia de Levenshtein en funciones SQL SERVER

Bueno... estoy buscando hacer un proyectico en la empresa y para eso estoy buscando cual es la mejor manera de implementar la distancia de Levenshtein. Y pues, la verdad, solo he encontrado tres funciones ya escritas, y de las cuales agradezco muchisimo a sus autores, pues me han ahorrado mucho tiempo.

La versión 1 es como la más corta en terminos de caracteres.
La versión 2 es como una versión un poco diferente a la 1, tiene un argumento más que es un número entero, y lo que hace según mis pruebas es que si supera el número de diferencias de caracteres me da como resultado un -1.
Y la versión 3, es una versión que creo que toca modificarla alguito, porque me esta sacando error.

Entonces doy las gracias a:


Arnold Fribble http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=51540

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=66781

Y a Joseph http://www.merriampark.com/ldtsql.htm 

Los códigos son:

VERSIÓN 1


CREATE FUNCTION edit_distance(@s1 nvarchar(3999), @s2 nvarchar(3999))
RETURNS int
AS
BEGIN
  DECLARE @s1_len int, @s2_len int, @i int, @j int, @s1_char nchar, @c int, @c_temp int,
    @cv0 varbinary(8000), @cv1 varbinary(8000)
  SELECT @s1_len = LEN(@s1), @s2_len = LEN(@s2), @cv1 = 0x0000, @j = 1, @i = 1, @c = 0
  WHILE @j <= @s2_len
    SELECT @cv1 = @cv1 + CAST(@j AS binary(2)), @j = @j + 1
  WHILE @i <= @s1_len
  BEGIN
    SELECT @s1_char = SUBSTRING(@s1, @i, 1), @c = @i, @cv0 = CAST(@i AS binary(2)), @j = 1
    WHILE @j <= @s2_len
    BEGIN
      SET @c = @c + 1
      SET @c_temp = CAST(SUBSTRING(@cv1, @j+@j-1, 2) AS int) +
        CASE WHEN @s1_char = SUBSTRING(@s2, @j, 1) THEN 0 ELSE 1 END
      IF @c > @c_temp SET @c = @c_temp
      SET @c_temp = CAST(SUBSTRING(@cv1, @j+@j+1, 2) AS int)+1
      IF @c > @c_temp SET @c = @c_temp
      SELECT @cv0 = @cv0 + CAST(@c AS binary(2)), @j = @j + 1
    END
    SELECT @cv1 = @cv0, @i = @i + 1
  END
  RETURN @c
END


VERSIÓN 2


SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

CREATE FUNCTION edit_distance_within(@s nvarchar(4000), @t nvarchar(4000), @d int)
RETURNS int
AS
BEGIN
  DECLARE @sl int, @tl int, @i int, @j int, @sc nchar, @c int, @c1 int,
    @cv0 nvarchar(4000), @cv1 nvarchar(4000), @cmin int
  SELECT @sl = LEN(@s), @tl = LEN(@t), @cv1 = '', @j = 1, @i = 1, @c = 0
  WHILE @j <= @tl
    SELECT @cv1 = @cv1 + NCHAR(@j), @j = @j + 1
  WHILE @i <= @sl
  BEGIN
    SELECT @sc = SUBSTRING(@s, @i, 1), @c1 = @i, @c = @i, @cv0 = '', @j = 1, @cmin = 4000
    WHILE @j <= @tl
    BEGIN
      SET @c = @c + 1
      SET @c1 = @c1 - CASE WHEN @sc = SUBSTRING(@t, @j, 1) THEN 1 ELSE 0 END
      IF @c > @c1 SET @c = @c1
      SET @c1 = UNICODE(SUBSTRING(@cv1, @j, 1)) + 1
      IF @c > @c1 SET @c = @c1
      IF @c < @cmin SET @cmin = @c
      SELECT @cv0 = @cv0 + NCHAR(@c), @j = @j + 1
    END
    IF @cmin > @d BREAK
    SELECT @cv1 = @cv0, @i = @i + 1
  END
  RETURN CASE WHEN @cmin <= @d AND @c <= @d THEN @c ELSE -1 END
END
GO


VERSIÓN 3


CREATE function LEVENSHTEIN( @s varchar(50), @t
varchar(50) ) 
--Returns the Levenshtein Distance between strings s1
and s2.
--Original developer: Michael Gilleland   
http://www.merriampark.com/ld.htm
--Translated to TSQL by Joseph Gama
returns varchar(50)
as
BEGIN
DECLARE @d varchar(100), @LD int, @m int, @n int, @i
int, @j int,
@s_i char(1), @t_j char(1),@cost int
--Step 1
SET @n=LEN(@s)
SET @m=LEN(@t)
SET @d=replicate(CHAR(0),100)
If @n = 0
 BEGIN
 SET @LD = @m
 GOTO done
 END
If @m = 0
 BEGIN
 SET @LD = @n
 GOTO done
 END
--Step 2
SET @i=0
WHILE @i<=@n
 BEGIN
 SET @d=STUFF(@d,@i+1,1,CHAR(@i))--d(i, 0) = i
 SET @i=@i+1
 END

SET @i=0
WHILE @i<=@m
 BEGIN
 SET @d=STUFF(@d,@i*(@n+1)+1,1,CHAR(@i))--d(0, j) = j
 SET @i=@i+1
 END
--goto done
--Step 3
 SET @i=1
 WHILE @i<=@n
  BEGIN
  SET @s_i=(substring(@s,@i,1))
--Step 4
 SET @j=1
 WHILE @j<=@m
  BEGIN
  SET @t_j=(substring(@t,@j,1))
  --Step 5
  If @s_i = @t_j
   SET @cost=0
  ELSE
   SET @cost=1
--Step 6
  SET @d=STUFF(@d,@j*(@n+1)+@i+1,1,CHAR(dbo.MIN3(
  ASCII(substring(@d,@j*(@n+1)+@i-1+1,1))+1,
  ASCII(substring(@d,(@j-1)*(@n+1)+@i+1,1))+1,
  ASCII(substring(@d,(@j-1)*(@n+1)+@i-1+1,1))+@cost)
  ))
  SET @j=@j+1
  END
 SET @i=@i+1
 END      
--Step 7
SET @LD = ASCII(substring(@d,@n*(@m+1)+@m+1,1))
done:
--RETURN @LD
--I kept this code that can be used to display the
matrix with all calculated values
--From Query Analyser it provides a nice way to check
the algorithm in action
--
RETURN @LD
--declare @z varchar(255)
--set @z=''
--SET @i=0
--WHILE @i<=@n
-- BEGIN
-- SET @j=0
-- WHILE @j<=@m
--  BEGIN
--  set
@z=@z+CONVERT(char(3),ASCII(substring(@d,@i*(@m+1
)+@j+1 ,1)))
--  SET @j=@j+1 
--  END
-- SET @i=@i+1
-- END
--print dbo.wrap(@z,3*(@n+1))
END


Sean felices! :) Y sientanse libres de opinar ;)

No hay comentarios:

Publicar un comentario

Palabras Clave

.NET (93) AJAX (2) ajaxcontroltoolkit (2) Algoritmos (1) android (1) Angular (1) Arrays (1) AS2 o ActionScript 2.0 (1) AS3 o ActionScript 3.0 (64) ASP (7) ASP.NET (3) Azure (1) Azure DevOps (2) Backup (2) Batch (4) blogger (1) Browser Support (2) C# (53) Charts (1) Chorme extensions (1) Chrome (3) cmd (18) código postal (1) Colombia tips (1) command (1) Conexion remota (1) Controles Web .NET (24) Cookies (1) cordova (1) CSS (14) CSV (5) Cufon (1) DateTime (2) deployment (2) Desarrollo movil (2) Desarrollo web (5) Diseño (4) DNN o DotNetNuke (5) docker (1) Encuestas (1) Entity Framework (1) Error (1) Eval (2) Excel (4) Expresiones regulares (2) Facebook (14) fechas (1) Fiddler (1) FileUpload (1) Filezilla (1) Firefox (2) Flash (9) Fonts (3) FQL (1) frameworks (2) Futuro de la web (1) git (1) Google Code (13) Google Maps (4) hackintosh (3) hazard 10.6.2 (3) herramientas para developers (1) highchart (1) Hilos (2) Hosting Windows (18) HTML (38) HTML5 (6) IDE (1) IE (2) IE9 (1) IIS (13) imagenes (3) jasmine (2) java (1) jqgrid (2) Jquery y Javascript (90) jquery-ui (5) jQueryMobile (1) JSON (1) knockout (4) library (1) Link Interesantes (2) List (1) Macro (2) Matemáticas (2) Membership (6) Memoria (1) Mis Experiencias (3) momentjs (1) ms-dos (1) MSN (1) MVC (1) MVC4 (3) MySQL (2) node.js (4) Notepad++ (3) Notificaciones (1) ObjectDataSource (2) Online (2) Opinión (4) OSX (3) Parallels Plesk Panel (1) petapoco (1) PhantomJS (1) PHP (4) Porqué este blog (1) Powershell (1) Razor (3) Redes (2) REGEX (4) REST (1) SDK Android (1) Seguridad (1) SelectParameters (1) Selenium (2) sencha (3) sencha cmd (2) SEO (1) SMTP (2) Software útil (8) Solución (1) Soporte (1) SQL (15) SQL Server (58) SQLite (2) Store Procedures (20) String (5) Testing Code (2) texto (2) tips de datos (1) tips de desarrollo (1) TutoFaceAS3 (4) TutoProAS3 (4) Tutoriales (7) Tweenlite effects (3) Últimas noticias (1) unit testing (1) usb (1) VBA (1) Video (1) virus (1) Web API (2) Web Browsers (1) Web Forms (7) web.config (1) Webmaster (8) Webmatrix (1) webrole (1) webservices (1) webstorm (1) Win Forms (5) Windows (21) Windows 7 (1) Windows 8 (1) XML (2) Youtube API (2)