Il suono delle cose

Ogni cosa ha un suono... anche i nomi :) e questo può tornare utile soprattutto nelle ricerche. In questo breve post vi illustro una mia versione di Soundex. Soundex è un algoritmo di fonetica per l’indicizzazione di parole secondo il loro suono o pronuncia. Nato essenzialmente per la pronuncia inglese, può essere trasportato in altre lingue come l’italiano. L’obiettivo è di poter raggruppare parole omofone (dal suono simile) affinché possano essere abbinate per un ricerca veloce, nonostante differenze o errori di ortografia. In un database di prodotti, la ricerca di "MATITA" troverà corrispondenze con "MATITA" e "MATITE", ma anche con "MATTITA". L’algoritmo di codifica prende in esame principalmente le consonanti; una vocale non viene codificata a meno che non sia la prima lettera della parola. Soundex è il più noto di tutti gli algoritmi fonetici, ce ne sono altri anche più sofisticati. Io ho implementato questo adattandolo alle mie esigenze. Funziona in modo molto semplice, produce un codice alfabetico (che di solito è lungo 4 caratteri, nella mia versione è possibile specificarne la lunghezza per affinare il dettaglio) composto dalla lettera iniziale della parola e da una codifica delle lettere restanti in valori numerici secondo una tabella standard (per cui letetre che hanno suono simile vengono codificate con lo stesso numero: C, G, K, Q ). Ad esempio, MATTONE è codificato come M350; MATTINO e METANO hanno la stessa codifica M350 (e infatti hanno un suono simile). In una casella di ricerca basata su Soundex questi nomi verrebbero trovati e visualizzati insieme perchè omofoni. L’algoritmo può risultare utile per minimizzare i costi degli errori di battitura, ad es. in un database di documenti organizzati secondo l’oggetto la ricerca documentale troverebbe anche quei documenti in cui l’oggetto viene digitato male o in modo simile ("lettera", "leetera", "letera", ecc.). Utilizzo: codice = soundex("stringa", numero_caratteri, pre_codifica?) dove stringa è un valore di tipo testo da codificare; numero_caratteri è la lunghezza del codice restituito (più il numero è alto e più accurato è il confronto tra le parole). Il valore predefinito è 4. Il valore booleano pre_codifica, True o False, è solo per debug e restituisce una coppia di valori stringa separati da virgola, in cui il primo valore è la parola depurata dai caratteri non codificabili e la seconda è la codifica risultante dall’applicazione dell’algoritmo. Segue il codice, ampiamente commentato.
Function soundex(s As String, Optional digits As Integer = 4, _
    Optional show_raw As Boolean = False) As String

Dim m As String, i As Integer, t As String, raw As String, char As String

    'se la lunghezza di caratteri da restituire è un numero fuori limite
    '(negativo oppure > 100 restituisce il valore di errore "#VALORE!")
    If digits < 0 Or digits > 100 Then
        soundex = "#VALORE!"
        Exit Function
    End If
    
    'trasforma la stringa in tutto maiuscolo
    s = UCase(s)
    
    'elimina i caratteri non ASCII (accentate e simboli)
    For i = 1 To Len(s)
        If (Mid(s, i, 1) Like "[!A-Z]") Then
            s = Replace(s, Mid(s, i, 1), "")
            i = i - 1
        End If
    Next
    
    'conserva il primo carattere della stringa che ne rappresenta una specie
    'di impronta digitale
    soundex = Left(s, 1)
    
    'scorre l'intero contenuto della stringa dal secondo carattere in poi
    For i = 2 To Len(s)
        'considera carattere per carattere
        char = Mid(s, i, 1)
        'non tiene conto delle lettere doppie, che vengono ignorate
        If char <> Mid(s, i - 1, 1) Then
            'assegna il codice numerico ad ogni lettera in base allo schema
            'standard che segue
            Select Case char
            Case "B", "F", "P", "V"
                m = m & "1"
                
            Case "C", "G", "J", "K", "Q", "S", "X", "Z"
                m = m & "2"
                
            Case "D", "T"
                m = m & "3"
                
            Case "L"
                m = m & "4"
                
            Case "M", "N"
                m = m & "5"
                
            Case "R"
                m = m & "6"
                
            End Select
            
            'rappresentazione grezza pre-codifica: conserva il carattere
            'se è tra quelli ammissibili (ignora vocali e straniere)
            If char Like "[!AEIOUYWH]" Then raw = raw & char
        End If
    Next
    
    'si prepara a ricevere la stringa codificata (riserva uno spazio grande)
    m = m & String(100, "0")
    'compone la stringa codificata considerando solo il numero di caratteri
    'passato in argomento quando la funzione è stata chiamata
    soundex = Left(soundex & m, digits)
    
    'se è stata chiesta anche la rappresentazione grezza pre_codifica,
    'restituisce una coppia di valori separati da virgola
    If show_raw Then soundex = _
        Left(Left(s, 1) & raw & String(100, "0"), digits) & "," & soundex
    
End Function

posted @ mercoledì 7 novembre 2012 00:13

Print

Comments on this entry:

No comments posted yet.

Your comment:



 (will not be displayed)


 
 
 
Please add 2 and 7 and type the answer here:
 

Live Comment Preview: