Estou parecendo louco por uma explicação de um algoritmo diff que funciona e é eficiente.
O mais próximo que cheguei foi desse link para o RFC 3284 (de várias postagens no blog Eric Sink), que descreve em termos perfeitamente compreensíveis o formato de dados no qual os resultados do diff são armazenados. No entanto, não há menção alguma sobre como um programa alcançaria esses resultados ao fazer uma comparação.
Estou tentando pesquisar isso por curiosidade pessoal, porque tenho certeza de que deve haver vantagens e desvantagens ao implementar um algoritmo diff, que às vezes é bastante claro quando você olha para diffs e se pergunta "por que o programa diff escolheu isso como uma alteração ao invés disso?"...
Onde posso encontrar uma descrição de um algoritmo eficiente que acabaria gerando VCDIFF?
A propósito, se você encontrar uma descrição do algoritmo real usado pelo DiffMerge da SourceGear, isso seria ainda melhor.
NOTA: a subsequência comum mais longa não parece ser o algoritmo usado pelo VCDIFF, parece que eles estão fazendo algo mais inteligente, considerando o formato de dados que usam.
Respostas:
Um algoritmo de diferença O (ND) e suas variações é um artigo fantástico e você pode começar por aí. Inclui pseudo-código e uma boa visualização dos percursos gráficos envolvidos na execução do diff.
A seção 4 do artigo introduz alguns refinamentos no algoritmo que o tornam muito eficaz.
A implementação bem-sucedida disso deixará uma ferramenta muito útil na sua caixa de ferramentas (e provavelmente também uma excelente experiência).
Às vezes, a geração do formato de saída necessário pode ser complicada, mas se você entender os detalhes internos do algoritmo, poderá produzir o que precisar. Você também pode introduzir heurísticas para afetar a saída e fazer certas trocas.
Aqui está uma página que inclui um pouco de documentação, código fonte completo e exemplos de um algoritmo diff usando as técnicas do algoritmo mencionado acima.
O código fonte parece seguir de perto o algoritmo básico e é fácil de ler.
Também há um pouco na preparação da entrada, o que você pode achar útil. Há uma enorme diferença na saída quando você está diferenciando por caractere ou token (palavra).
Boa sorte!
fonte
diff
artigo do Unix de Hunt e McIlroy.Eu começaria examinando o código fonte real do diff, que o GNU disponibiliza .
Para entender como esse código-fonte realmente funciona, os documentos desse pacote fazem referência aos documentos que o inspiraram:
Ler os documentos e examinar o código fonte de uma implementação deve ser mais do que suficiente para entender como ele funciona.
fonte
Consulte https://github.com/google/diff-match-patch
Veja também a página Diff do wikipedia.org e - " Bram Cohen: O problema do diff foi resolvido "
fonte
Eu vim aqui procurando o algoritmo diff e depois fiz minha própria implementação. Desculpe, eu não sei sobre vcdiff.
Wikipedia : De uma subsequência comum mais longa, é apenas um pequeno passo para obter uma saída do tipo diff: se um item estiver ausente na subsequência, mas presente no original, ele deverá ter sido excluído. (As marcas '-', abaixo.) Se estiver ausente na subsequência, mas presente na segunda sequência, deve ter sido adicionado. (As marcas '+'.)
Boa animação do algoritmo LCS aqui .
Link para uma implementação rápida do LCS ruby aqui .
Minha lenta e simples adaptação a rubi está abaixo.
fonte
Com base no link que Emmelaich deu, também há uma grande quantidade de Diff Strategies no site de Neil Fraser (um dos autores da biblioteca) .
Ele aborda estratégias básicas e, no final do artigo, avança para o algoritmo de Myer e alguma teoria dos grafos.
fonte