Nous avons une exigence dans le projet que nous devons comparer deux textes (update1, update2) et trouver un algorithme pour définir combien de mots et combien de phrases ont changé.
Y a-t-il des algorithmes que je peux utiliser?
Je ne cherche même pas de code. Si je connais l'algorithme, je peux le coder en Java.
Généralement, cela est accompli en trouvant Longest Common Subsequence (communément appelé le problème LCS). Voici comment fonctionnent des outils comme diff
. Bien sûr, diff
est un outil orienté ligne, et il semble que vos besoins soient quelque peu différents. Cependant, je suppose que vous avez déjà construit un moyen de comparer les mots et les phrases.
n O(NP) algorithme de comparaison de séquence est utilisé par le moteur de diff de Subversion.
Pour votre information, il existe des implémentations avec différents langages de programmation par moi-même dans la page suivante de github.
Une sorte de variante de diff pourrait être utile, par exemple wdiff
Si vous décidez de concevoir votre propre algorithme, vous devrez faire face à la situation où une phrase a été insérée. Par exemple pour les deux documents suivants:
The men are bad. I hate the men
et
The men are bad. John likes the men. I hate the men
Votre outil devrait être en mesure de regarder en avant pour reconnaître que dans le second, I hate the men
n'a pas été remplacé par John likes the men
mais n'est pas modifié et une nouvelle phrase est insérée avant. c'est-à-dire qu'il doit signaler l'insertion d'une phrase, pas le changement de quatre mots suivi d'une nouvelle phrase.
L'algorithme spécifique utilisé par diff et la plupart des autres utilitaires de comparaison est Eugene Myer n O(ND) algorithme de différence et ses variations . Il y a un Java implémentation de celui-ci disponible dans le paquet Java-diff-utils .
Voici deux articles qui décrivent d'autres algorithmes de comparaison de texte qui devraient généralement produire des différences `` meilleures '' (par exemple, plus petites et plus significatives):
Le premier article cite le second et le mentionne à propos de son algorithme:
Heckel [3] a souligné des problèmes similaires avec les techniques LCS et a proposé un algorithme de chaux linéaire pour détecter les mouvements de blocs. L'algorithme fonctionne correctement s'il y a peu de symboles en double dans les chaînes. Cependant, l'algorithme donne des résultats médiocres autrement. Par exemple, étant donné les deux chaînes aabb et bbaa , l'algorithme de Heckel échoue pour découvrir une sous-chaîne commune.
Le premier article a été mentionné dans cette réponse et le second dans cette réponse , tous deux à la même question SO question:
La difficulté vient de la comparaison efficace et de bonnes performances de fichiers volumineux. J'ai donc implémenté une variante de Myers O(ND) algorithme diff - qui fonctionne assez bien et avec précision (et prend en charge le filtrage basé sur l'expression régulière):
L'algorithme peut être testé ici: application web de l'outil de comparaison becke.ch
Et un peu plus d'informations sur la page d'accueil: outil de comparaison becke.ch