Validar email con PHP

Validar email con PHP
A continuación dos modos de validar una dirección de email con php.
La primera mediante una expresión regular y la segunda mediante filter_var que se encarga de filtrar variables mediante filtros (valga la redundancia).
Como ejemplo, un pequeño formulario con un inputtype tipo texto y un botón de envío.

<HTML>
<HEAD></HEAD>

    <BODY>
        <p>Validando email</p>
        <form action="" method="post">
            <input type="text" value="" name="email"/>
            <input type="submit" value="validar" />
        </form>
    </BODY>
    <?php
    $email=isset($_POST['email']) ? $_POST['email'] :null;    
    if(validarEmail_ExpresionRegular($email)){          
            echo "Expresion Regular. La dirección de email $email es correcta.</br>";
    }
    else echo "Expresion Regular. La dirección de email $email es incorrecta.</br>";    
    
    if (is_valid_email_FilterVar($email)){
          
            print "Filter_var. La dirección de email $email es correcta.</br>";  
    }
    else print "Filter_var. La dirección de email $email es incorrecta.</br>"; 
    
    /* **********************************
    *  FUNCIONES DE VALIDACIÓN DE EMAIL *
    *************************************/
    
    // Función para validar email usando un expresión regular
    function validarEmail_ExpresionRegular($emailAValidar){
        $matches = null;
            return (1 === preg_match('/^[A-z0-9\\._-]+@[A-z0-9][A-z0-9-]*(\\.[A-z0-9_-]+)*\\.([A-z]{2,6})$/', $emailAValidar, $matches));
    }
    
    // Función para validar email usando un filter_var 
    // en la que se filtran variables mediante filtros (valga la redundancia)
    function is_valid_email_FilterVar($str)
    {
        return (false !== filter_var($str, FILTER_VALIDATE_EMAIL));
    }
?>
</HTML>
Anuncios

Descomposición factorial con hilos II

Descomposición factorial con hilos II
Y ahora vamos a emular un lugar donde se descomponen los números y cada vez que se encuentra uno, se obtiene y se muestra su descomposición.

Para realizar esto, usaremos los monitores de Java, los métodos wait() y notify(). Estos métodos tienen que ir siempre incluidos sobre métodos marcados como syncronized o usar el método syncronized(metodo sincronizado). wait() y notify() (hay alguno más) heredan del Object, por lo que todos los objetos que hereden de esta clase, lo tienen disponible.

¿Que hace wait()? suspende indefinidamente el hilo hasta que se reanude con notify().

Así que crearé una clase que solicitará la descomposición del número, el cual es enviado al supuesto servidor compartido de descomposiciones factoriales, este se encarga de descomponerlo (tarea dura) y una vez que termine, habrá un receptor de datos esperando a su finalización para mostrar su descomposición.

DESC

La clase SolicitudDescomposicionVisualizadorDescomposicion heredan de Thread, los iniciamos desde la clase principal y a trabajar por parte del servidor. He aquí el código:

public static void main(String[] args) {
        // TODO code application logic here
        
        ServidorDescomposicion r=new ServidorDescomposicion();
        for (int i = 0; i < 10; i++) {
            SolicitudDescomposicion productor=new SolicitudDescomposicion(i, r);
            VisualizadorDescomposicion consumidor=new VisualizadorDescomposicion(i, r);
            
            productor.start();
            consumidor.start();
        }
        
    }
public class SolicitudDescomposicion extends Thread {
    
    ServidorDescomposicion r;
    
    public SolicitudDescomposicion(int n, ServidorDescomposicion _r){
        this.setName("Productor " + n);
        r=_r;
    }
    
    @Override
    public void run(){
        int n=Math.abs(new Random().nextInt());
        System.out.println("Enviando número descomposición desde el productor:\t" + n);
        r.descomponerNumero(n);
    }
}

public class VisualizadorDescomposicion extends Thread{
    
    ServidorDescomposicion r;
    
    public VisualizadorDescomposicion(int n, ServidorDescomposicion _r){
        this.setName("Consumidor " + n);
        r=_r;
    }
    
    @Override
    public void run(){        
        String desc="";
        try {
            desc = r.getDescomposicion();
        } catch (InterruptedException ex) {
            Logger.getLogger(VisualizadorDescomposicion.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("Datos obtenidos desde el consumidor.Resultado:\t\t" + desc);        
    }
}
public class ServidorDescomposicion {

    ArrayList buffer;
    boolean existData;


    //&& estado.equals(estadoEnum.DESCOMPONIENDO
    //&& estado.equals(estadoEnum.LIBRE)
    public ServidorDescomposicion() {
        buffer = new ArrayList();
    }

    public synchronized void descomponerNumero(int numero) {
        descomponer(numero);
    }

    void retardo(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
            Logger.getLogger(ServidorDescomposicion.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public synchronized String getDescomposicion() throws InterruptedException {
        
        while(!existData){
            try {
                wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ServidorDescomposicion.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        String descomposicion = "";
        descomposicion = buffer.remove(0);
        if (buffer.size()==0) {
            existData=false;
        }
        notify();
        
        return descomposicion;
    }

    void descomponer(int numero) {
        // Cálculos y resultados
        int iniNum = numero;
        int numeroAux = numero;
        int n = 0;
        int nn = 0;

        String text = "";
        String puntos = ".";

        for (long i = 2; i < numero; i++) { 
            while (numeroAux % i == 0) {
                numeroAux /= i;
                text += i + ".";
                if (numeroAux == 1) {
                    numero = numeroAux;
                }
            }
        }
        if (text.isEmpty()) {
            System.out.printf("El número %s es primo!\n", iniNum);
            text = String.valueOf(iniNum);
        }
        buffer.add(String.format("%s=%s", iniNum, text));
        existData=true;

    }

}

y el resultado para 10 números enteros


Enviando número descomposición desde el productor:	1007666687
Enviando número descomposición desde el productor:	233955388
Enviando número descomposición desde el productor:	403028651
Enviando número descomposición desde el productor:	1405658987
Enviando número descomposición desde el productor:	809322159
Enviando número descomposición desde el productor:	263332588
Enviando número descomposición desde el productor:	1552584352
Enviando número descomposición desde el productor:	1342709543
Datos obtenidos desde el consumidor.Resultado:		1007666687=17.31.43.53.839.
Datos obtenidos desde el consumidor.Resultado:		1342709543=7.191815649.
Datos obtenidos desde el consumidor.Resultado:		1552584352=2.2.2.2.2.11.89.49559.
Datos obtenidos desde el consumidor.Resultado:		263332588=2.2.487.135181.
Datos obtenidos desde el consumidor.Resultado:		809322159=3.113.733.3257.
Datos obtenidos desde el consumidor.Resultado:		403028651=67.6015353.
Datos obtenidos desde el consumidor.Resultado:		233955388=2.2.31.443.4259.
Datos obtenidos desde el consumidor.Resultado:		1405658987=127.199.55619.

Saludos

Descomposición factorial con hilos I

Descomposición factorial con hilos I

Un ejemplo de aprovechamiento de recursos sobre procesos penosos en los que ponemos el pc a prueba, puede ser la descomposición de números grandes en factores primos. En este ejemplo sobre la plataforma Java, se descomponen números del tipo Long con un método estándar (no muy eficiente) con una clase que implementa la Interfaz Runnable. A la clase le pasamos un número como parámetro y otro de identificador.Si creamos varios hilos, cada uno descomponiendo un número grande, aprovechará los distintos núcleos para el cálculo. Este es el resultado para números enteros pequeños mostrando el número de hilos vivos.

INICIO Hilo nº0-> Descomposición de 1763458
INICIO Hilo nº2-> Descomposición de 882375341
INICIO Hilo nº3-> Descomposición de 396209470
INICIO Hilo nº1-> Descomposición de 1633289887
Hilo nº 0-> Descomponiendo 1763458. Nº iteraciones: 1
Hilo nº 2-> Descomponiendo 882375341. Nº iteraciones: 96
Hilo nº 3-> Descomponiendo 396209470. Nº iteraciones: 1
Hilo nº 3-> Descomponiendo 198104735. Nº iteraciones: 4
Hilo nº 3-> Descomponiendo 39620947. Nº iteraciones: 18
Hilo nº 3-> Descomponiendo 2085313. Nº iteraciones: 210
Hilo nº 1-> Descomponiendo 1633289887. Nº iteraciones: 66
Hilo nº 1-> Descomponiendo 24377461. Nº iteraciones: 100
Hilo nº 3-> Descomponiendo 9883. Nº iteraciones: 9882
FIN Hilo nº 3-> 396209470 = 2*5*19*211*9883*. Nº iteraciones: 9882
Quedan 3 hilos vivos
Hilo nº 2-> Descomponiendo 9096653. Nº iteraciones: 1810
Hilo nº 2-> Descomponiendo 5023. Nº iteraciones: 5022
FIN Hilo nº 2-> 882375341 = 97*1811*5023*. Nº iteraciones: 5022
Quedan 2 hilos vivos
Hilo nº 1-> Descomponiendo 241361. Nº iteraciones: 241360
FIN Hilo nº 1-> 1633289887 = 67*101*241361*. Nº iteraciones: 241360
Quedan 1 hilos vivos
Hilo nº 0-> Descomponiendo 881729. Nº iteraciones: 881728
FIN Hilo nº 0-> 1763458 = 2*881729*. Nº iteraciones: 881728
Quedan 0 hilos vivos

Y el código de las clases…

Clase Main

package Descompositor;

import java.util.Random;

// <editor-fold defaultstate="collapsed" desc="Cabecera de clase">
/******************************************************
 *  @author:    Joaquín Martínez Rus (c) 2017
 *  @version:   1.0
 *  File:       Main.java
 *  Created:    29/11/2017
 *  Project:    PSP. Ejemplo de descomposición multihilo.
 *  Comments:
 *******************************************************/
// </editor-fold>
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        for (int i = 0; i < 5; i++) {
            Descomposicion d=new Descomposicion(Math.abs(new Random().nextLong()),i);
            Thread hilo=new Thread(d);
            hilo.start();
        }
    }
}

y la clase encargada de la descomposición

package Descompositor;
import java.util.Date;
// <editor-fold defaultstate="collapsed" desc="Cabecera de clase">
/******************************************************
 *  @author:    Joaquín Martínez Rus (c) 2017
 *  @version:   1.0
 *  File:       Descomposicion.java
 *  Created:    29/11/2017
 *  Project:    PSP. Ejemplo de descomposición multihilo.
 *  Comments:
 *******************************************************/
// </editor-fold>
public class Descomposicion implements Runnable{

    public Descomposicion(long n, int j){
        this.name=j;
        this.number=n;
        Descomposicion.instanciasVivas++;
    }

    public static int instanciasVivas;
    int name;
    long number;

    @Override
    public void run() {
        descomponer(number, name);
    }

    void descomponer(long numero, int j){
        // Cálculos y resultados

        long iniNum=numero;
        long numeroAux = numero;
        long n=0;
        int nn=0;

        System.out.printf("INICIO Hilo nº%s-> Descomposición de %s\n" , j, numeroAux);
        String text="";
        String puntos=".";

        for (long i = 2; i 1000000000) {
                nn++;
                String cadena="Hilo Nº %s-> Seguimos calculando para %s...\n";
                if (nn>2) {
                    if (text.isEmpty()) {
                        cadena = "Hilo Nº %s-> parece que el número %s es primo...\n";
                    }
                    else{
                        cadena ="Hilo Nº %s-> No es primo y seguimos calculando para %s...\n";
                        nn=0;
                    }
                }
                System.out.printf(cadena, j, numeroAux);
                n=0;

            }
            // DESCOMPOSICIÓN
            while (numeroAux % i == 0) {
                System.out.printf("Hilo nº %s-> Descomponiendo %s. Nº iteraciones: %s\n",j, numeroAux, n);
                numeroAux /= i;
                text += i + "*";
                if (numeroAux == 1) {
                    numero=numeroAux;
                }
            }
        }
        if (text.isEmpty()){
            System.out.printf("El número %s es primo!\n",iniNum);
            text = String.valueOf(iniNum);
        }
        System.out.printf("FIN Hilo nº %s-> %s = %s. Nº iteraciones: %s\n",j, iniNum, text, n);

        Descomposicion.instanciasVivas--;
        System.out.printf("Quedan %s hilos vivos\n",Descomposicion.instanciasVivas);

    }
}

Os adjunto el proyecto de NetBeans.

Saludos

 

Atajos en Android Studio

Atajos en Android Studio

Como no iba a ser menos, Android Studio también tiene algunos atajos o métodos abreviados para simplificar la escritura de código y he aquí algunos ejemplos útiles.

¿Cuáles son estas abreviaturas? Pues si pulsamos CTRL + J nos muestra en una lista todos ellas.
Pulsando por ejemplo it y CTRL + J, mostraría lo siguiente
abrev01
y escribiendo st + TAB escribe String
Si declaramos por ejemplo un array y luego itar + TAB se genera el siguiente código

String [] array=new String[3];
for (int i = 0; i < array.length; i++) {
       String s = array[i];                    
}

Hay muchas abreviaturas, pero por otra parte, existen combinaciones de teclas y a mi personalmente, me gustan las siguientes:

Cuando vamos a hacer un cast, escribimos el paréntesis y CTRL + MAYUSC + SPC y se completa automáticamente

String a=( CTRL + MAYUSC + SPC → String a=(String)
CTRL + SPC nos muestra las sugerencias en el contexto actual. Si escribimos nu…abrev02

CTRL + P entre los paréntesis donde se albergan los parámetros de un método, nos muestra una ayuda de los parámetros

abrev03

CTRL + / o CTRL + MAYUSC + / comenta mediante // o /**/ respectivamente las líneas

ALT + CTRL + L formatea el código

CTRL + click sobre un objeto o método, navega hasta la declaración de este

CTRL + MAYUSC + RETROCESO, navega hasta el último lugar donde realizamos la última edición.

…  y muchos más.

 

Documentar el código

Documentar el código

El código además de ser limpio, legible, entendible o estructurado entre otras características, debe estar muy bien documentado con el fin de efectuar un mantenimiento, modificación o ampliación de nuestra fuente. Además, es posible generar documentación en base a estos comentarios como es el caso de JavaDoc.

Existen muchas formas de comentar el código, por ejemplo:

C#, Java, PHP, etc.

  • Solo C#. Podemos hacerlo con tres barras /// en la que al crear una nueva línea, la siguiente línea queda también comentada con ///. Si las escribimos antes de una clase o un método, genera etiquetas de comentario que expondré a continuación.
  • Dos barras, crea una línea de código comentado
  • Comentario multilínea. Una barra y un asterisco /* provoca que el código esté comentado hasta que se cierre el comentario con asterisco barra */

Visual basic.NET

  • Comillas simples para comentar línea. ‘Esto es un comentario en VB.NET
  • Usar la etiqueta REM. REM Esto es un comentario en VB.NET
  • Si queremos crear varias líneas, debemos usar el concatenador guión bajo
    REM Esto es un comentario_ 
    en VB.NET

HTML

  • para cerrar el comentario

Comentarios de clases y métodos

Cuando estamos escribiendo código e instanciamos una clase o seleccionamos un método de una clase, los IDE,s nos muestran una ayuda que nos muestra que hace el método, que parámetros tiene o que sobrecargas y esto se consigue del siguiente modo:

C#

    • Escribimos /// precediendo a una clase o un método y se generan automáticamente una serie de etiquetas xml. La documentación de las etiquetas la pueden encontrar en el siguiente enlace.
      /// <summary>
      /// Obtiene el nombre completo del objeto Persona
      /// </summary>
      /// <param name="dni">DNI del objeto persona</param>
      /// <returns>Cadena de texto con el nombre completo</returns>
      public string GetFullName(string dni)
      {
      	return "Joaquín Martínez;
      }
      
      /// <summary>
      /// Obtiene el nombre completo del objeto Persona
      /// </summary>
      /// <param name="id">Identificador del objeto persona</param>
      /// <returns>Cadena de texto con el nombre completo</returns>
      public string GetFullName(int id)
      {
      	return "Joaquín Martínez;
      }
      

Java

    • Escribimos encima de un método /** e INTRO y se genera las etiquetas para documentar el código
      /**
      * Obtiene el nombre completo del objeto Persona
      * @param dni DNI del objeto persona
      * @return Cadena de texto con el nombre completo
      */
      public String getFullName(String dni){
      	return "Joaquín Martínez";
      }
      
      /**
      * Obtiene el nombre completo del objeto Persona
      * @param id Identificador del objeto persona
      * @return Cadena de texto con el nombre completo
      */
      public String getFullName(int id){
      	return "Joaquín Martínez";
      }
      

      coment04coment05

Regiones

Otra forma de mantener el código ordenado es mediante regiones, esto nos va a permitir por ejemplo mantener en una clase de negocio los métodos de actualización, adición y eliminación separados de los de selección, mantener propiedades en una región, campos en otra, métodos públicos en otra, privados en otra y así cuantas regiones queramos tener con el fin de mantener el código ordenado. Yo personalmente en una clase, generalizando, siempre tengo una región para constructores y destructores, una para enumeraciones, una para campos, una para métodos públicos y protected, otra para privados y si la clase es un form o window, añado una para controles y dentro de esta, por tipo de control, añado métodos de evento de cada uno, por ejemplo, Buttons, DataGrid, etc.

C#

#region Métodos públicos
        // aquí podemos poner todos los
        // miembros de clase que queramos
#endregion

VB.NET

#Region "Métodos Públicos"
' aquí podemos poner todos los
' miembros de clase que queramos
#End Region

def45-7-2-1
Java

// <editor-fold desc="Métodos públicos" defaultstate="collapsed">
        // aquí podemos poner todos los
        // miembros de clase que queramos
// </editor-fold>

coment06.png

Tareas

Visual Studio tiene comentarios de tareas, es decir si incluimos una serie de comentarios específicos (TOKEN) en alguna parte del código con un comentario adicional, en la lista de tareas, podemos acceder a esta localización de código para continuar con la tarea pendiente. Estos Token pueden personalizarse en el Menú Herramientas, Opciones, Lista de tareas. En este ejemplo, he colocado un TOKEN para revisar el contenido del método y en la lista de tareas, al hacer doble click, nos dirigiremos al código en cuestión.

coment07.png

Hay que añadir y es una buena costumbre, documentar las clases con autoría, fechas de creación y modificación, que hace la clase, que función tiene, las modificaciones que se han realizado, etc.

Hacedme caso, un poco tiempo perdido en documentar, nos hará ganar muchísimo tiempo en un futuro.

coment08.png

 

Atajos Netbeans

Atajos Netbeans

Todos los IDE,s tienen una serie de mejoras que nos ayudan a escribir código de manera fácil y evitando errores, en este caso Netbeans no podía ser menos.

¿Que son los atajos de Netbeans? Son palabras que nos permiten escribir bloques de código de una manera rápida evitando repetir estructuras continuamente. Lo primero de todo que son muy prácticos y lo segundo que evitan muchos errores, (causan otros), pero creo que las ventajas son muy superiores a los pocos inconvenientes que pudiera tener. Para el que no esté familiarizado con el código, lo mejor sería teclear todas las instrucciones letra por letra y olvidarse de los atajos por una temporada hasta que controléis la mayoría de las instrucciones. Hay dos tipos, uno mediante combinación de teclas y otros escribiendo palabras + TAB.

Las combinaciones de teclas, pueden visualizarse en los menús y menús contextuales. Alguno de los ejemplos de combinación de teclas:

  • CTRL + SPACE→ o completa la palabra que estamos intentando escribir o nos muestra una lista con las sugerencias.
  • ALT + ENTER→ Si nuestro código se encuentra subrayado en rojo, nos muestra que podemos hacer. Si instanciamos Scanner y no tenemos importado java.util.Scanner, al combinar sobre este nos mostrará lo mismo que si pulsamos sobre la bombilla de sugerencias.
  • CTRL + R→Imaginad que tenemos una variable en 20 sitios distintos, pues si nos situamos sobre ella y usamos este atajo, nos resalta todas las variables en el código pudiendo detectarlas con más facilidad.
  • ALT + SHIFT+ F →Da formato al código
  • CTRL + E → Borra líneas de código CTRL+ SHIFT+ Flecha Arriba o Abajo →Copia líneas de código
  • ALT + SHIFT+ Flecha Arriba o Abajo →Sube o baja líneas de código
  • CTRL + SHIFT + B. Navega hasta la fuente del código.
  • CTRL + B. Navega hasta la declaración
  • ALT + F7. Busca todas las referencias usadas en los proyectos abiertos
  • F6. Ejecuta el proyecto
  • CTRL + F5. Ejecuta en modo depuración

Ejemplos de palabras + TAB.

atajos01También es posible usar CTRL + SPACE cuando estemos escribiendo alguna de estas palabras y nos mostrará las sugerencias. Todos estos atajos están al principio de la lista marcados con un icono cuando pusalmos CTRL + SPACE

  • sout + TAB → System.out.println(“”)
  • soutv + TAB → System.out.println(“this = ” + this);
  • serr + TAB → System.err.println(“”);
  • for +TAB → for (int i = 0; i < 10; i++) { }
  • forc + TAB → for (Iterator iterator = col.iterator(); iterator.hasNext();) {Object next = iterator.next();}
  • fore + TAB → for (String arg : args) { }
  • whilexp +TAB → while (true) { }
  • do +TAB → do { } while (true);
  • if +TAB → if (true) { }
  • ifelse +TAB → if (true) { } else { }
  • sw +TAB → switch (var) { case val: break; default: throw new AssertionError(); }
  • trycatch → try { } catch (Exception e) { }
  • fcom →región de código
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    ...
    // </editor-fold>

una vez que los escribimos, hay que tener en cuenta que algunos de ellos debemos completarlos (de ahí los posibles errores). Por ejemplo, sw que genera el bloque de código switch hay que escribir el valor de la variable y los valores de cada caso, si no el código nos daría error. El bloque de código fore, se debe indicar la colección o forc hay que indicar el iterator.

Espero que os sirva de ayuda aunque reitero que si no estáis familiarizados con el código hay que escribirlo mil veces hasta que nos suene antes de usar atajos.

Distancia de Levenshtein

Distancia de Levenshtein

La distancia de Levenshtein es el número mínimo que necesitamos para convertir una palabra en otra, un ejemplo pelo y perro tienen tienen una distancia de 2 porque tendríamos que sustituir la l por una r y añadir una r, dos movimientos, distancia 2. Otro ejemplo, murcielago y muerdago que tienen una distancia de 5, ya que a murciélago le tenemos que quitar c,i,e,l y a muerdago le quitamos la d, por tanto necesitamos 5 movimientos para convertir una palabra en otra. Resumiendo, cuanto más pequeña sea la distancia, más parecidas son las dos palabras.

¿Esto para que sirve?, pues muy fácil, para obtener palabras similares en los buscadores o mostrar palabras alternativas por ejemplo. Vamos a ver el algoritmo y como funciona.

Este algoritmo es una matriz de n filas por m columnas donde n y m son el número de caracteres + 1 de cada palabra. El primer paso que se realiza es rellenar la primera fila y la primera columna con números secuenciales de 0 hasta n+1 y desde 0 hasta m+1 , quedando del siguiente modo para el caso del ejemplo inicial la matriz de 11×9:

levensthein0Una vez tenemos la matriz inicial, empezaremos a realizar comparaciones por filas de cada caracter con el caracter de cada columna. En cada operación, obtenemos primero el peso y tres valores de los cuales deduciremos el menor de ellos como valor final y con un ejemplo lo veremos mejor.

Comenzamos comparando los caracteres, la letra “m” de murcielago (en la columna), lo comparamos con la “m” de muerdago (filas), si es el mismo caracter se le asigna un peso de 0 y si es diferente, le asignamos 1, en este caso como son iguales, le asignamos un 0. A continuación obtenemos los tres valores, el primero con la casilla superior sumándole al valor de esta un 1, en este caso 1+1=2, el siguiente con la casilla que está situada a su izquierda haciéndolo de igual modo, 1+1=2 y por último a la casilla superior izquierda, la que está situada en la diagonal a la que le sumaremos el valor del peso, 0+0=0; de estos tres valores, cogeremos el menor que en este caso es el 0. levensthein1

Vamos a por el siguiente, peso igual a 0, porque u es igual a u, por la izquierda, 0+1=1, la diagonal 1+0=1 y la superior 1+2=2, el mínimo de los tres es 1

levensthein2

continuando con las comparaciones y obtención del mínimo, quedaría nuestra matriz completa del siguiente modo:

levensthein3

El último valor, es la distancia de Levenshtein, en este caso es 5, si quisieramos ver la proporción de acierto, deberíamos obtener la la diferencia con la unidad de la relación entre la distancia y el número de caracteres del mayor en este caso, 1 – (5/10)=0,5 o 50%. La distancia de “murcielago” y “cerro muriano” es de 10, por tanto 1-(10/13)=0.2308 o del 23,08%.

El algoritmo implementado con lenguajes de programación no tiene ningún misterio para el que esté acostumbrado a las matrices, además en Wikipedia, podéis encontrar su implementación en diferentes lenguajes, por ejemplo en php ya tiene una función como tal.

vladimir-levenshtein¿Que utilidades podemos darle? por ejemplo palabras sugerentes en base a un diccionario o aproximaciones, corrección de ortografía, etc. y además, existen variantes del algoritmo como la de Damerau-Levenshtein, otros más complejos, algoritmos fonéticos.

Este algoritmo se lo debemos a Vladimir Levenshtein, un matemático ruso que lo desarrolló en 1965.

He hecho en C# una app de consola como muestra para obtener la matriz y en base a un diccionario, nos muestre sugerencia de palabra.  levensthein4

levensthein5