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.
algorithms
strings
Reactgular
fonte
fonte
Respostas:
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
->sitting
que tem uma distância de edição de trêsExistem 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:
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:
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:
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*M
espaço para o outro2*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).fonte