Combine duas strings, mas permita um grau de erro


10

Como posso combinar duas strings, mas ao mesmo tempo permitir que o número X de caracteres esteja incorreto na correspondência. O número de erros deve ser uma variável controlável.

Embora o número X de caracteres não possa corresponder à sequência, deve haver um limite para o número de execuções em uma sequência. Dadas duas seqüências, posso permitir que 5 caracteres sejam diferentes, mas não mais que 2 seguidos.

Estou procurando um algoritmo recomendado para comparar essas duas strings, ou talvez já exista uma solução conhecida para isso.


4
A distância de Levenshtein pode ser algo para se olhar, embora as especificidades de 'não mais que 2 seguidas' não façam parte desse algoritmo. A página ver também possui muitos outros algoritmos relacionados que podem ser o que você está procurando.

@ MichaelT, se eu tivesse algo assim, definitivamente atenderia às minhas necessidades. obrigado.
Reactgular

@MichaelT Encontrei isso> dotnetperls.com/levenshtein Você deve colocar isso como a resposta, pois isso resolveu meus problemas.
Reactgular

Você pode querer olhar para a correspondência Soundex. en.wikipedia.org/wiki/Soundex
Gilbert Le Blanc

Respostas:


12

Um ponto de partida aproximado da pesquisa de cadeias é o da distância de Levenshtein . Esse algoritmo conta o número de edições de um único caractere (inserção, exclusão e substituição) para alterar uma palavra em outra.

Um exemplo disso é kitten-> sittingque tem uma distância de edição de três

  1. k itten -> s itten (substitua 's' por 'k')
  2. sitt e n -> sitt i n (substitua 'i' por 'e')
  3. sittin -> sittin g (adicione 'g' no final)

Existem variações nesse algoritmo, notadamente a distância Damerau – Levenshtein, que permite a transposição de dois caracteres adjacentes ('hte' para 'the' tem uma distância DL de 1 e uma distância Levenshtein de 2) e, portanto, muitas vezes é mais apropriado para verificação ortográfica. Existem outras variações para aplicações em que as lacunas são importantes (cadeias de DNA).

A distância de Levenshtein é bem conhecida e não é muito difícil de encontrar (uma vez tive motivos para buscar uma implementação dela como uma função no oracle - era muito mais rápido do que baixar todos os dados e depois executar o lado do código de consulta). O Rosettacode possui uma infinidade (54) de implementações da distância Levenshtein (observe que algumas linguagens têm isso como parte da biblioteca de cadeias em algum lugar - se você estiver executando Java, observe o apache commons lang ). O Wikilivros possui 31 implementações e uma rápida olhada nos dois não mostra o mesmo código para o mesmo idioma.

A maneira como isso funciona é construir uma matriz que corresponde ao relacionamento entre as duas strings:

 .kitten
.0123456
s1123456
i2212345
t3321234
t4432123
i5543223
n6654332
g7765443

A .linha e a coluna representam que você pode chegar à string de destino inserindo 'apenas' cada letra de uma string vazia. Este não é o caso ideal, mas existe para propagar o algoritmo.

Se o valor for o mesmo desse ponto ('i' == 'i'), o valor será o mesmo que o valor na diagonal à esquerda. Se os dois pontos forem diferentes ('s'! = 'K'), o valor será o mínimo de:

  • diagonal para cima e para a esquerda + 1 (uma substituição)
  • diretamente acima de + 1 (uma inserção)
  • diretamente à esquerda + 1 (uma exclusão)

O valor de retorno da distância de edição é o valor no canto inferior direito da matriz.

Se você seguir do canto inferior direito para o canto superior esquerdo com o mínimo, poderá ver as edições feitas:

 .kitten
.0.   .
s.1   .
i  1  .
t   1 .
t    1.
i.....2
n      2
g......3

Observe que essa é a abordagem que consome muita memória. Ele pode ser reduzido no escopo da memória, não criando a matriz completa - tudo o que o algoritmo se importa é um subconjunto dos dados e pode ser reduzido de um N*Mespaço para o outro 2*max(N,M)apenas armazenando a linha anterior (e o que foi calculado na corrente linha). Projeto de código mostra como isso pode ser feito (com código C # para download).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.