Cela dépend principalement de votre utilisation des modifications de texte. Lorsque la séquence comprend à la fois des insertions et des suppressions, il est théoriquement impossible de connaître les détails de chaque insertion, car certains des symboles insérés peuvent avoir été supprimés par la suite. Par conséquent, vous devez choisir ce que vous voulez vraiment les résultats:
- Pour certaines fins, vous devez connaître la séquence exacte des changements, même si certains des symboles insérés doit être laissé comme « ? ».
- À d'autres fins, vous devez savoir exactement comment le nouveau texte diffère de l'ancien, mais pas la séquence exacte dans laquelle les modifications ont été apportées.
Je vais techniques pour atteindre chacun de ces résultats. J'ai utilisé les deux techniques dans le passé, donc je sais qu'elles sont efficaces.
Pour obtenir la séquence exacte
Ceci est plus approprié si vous implémentez une histoire ou d'annuler journal ou à la recherche d'actions spécifiques. Pour ces utilisations, le processus que vous décrivez est probablement le meilleur, avec un changement possible: Au lieu de "trouver les correspondances entre les symboles inconnus et les vrais", il suffit de lancer le balayage pour trouver le texte de chaque "puis lancez-le en arrière pour trouver le texte de chaque" Insert ".
En d'autres termes:
Commencez avec le texte initial et le processus des changements dans l'ordre. Pour chaque insertion, insérez '?' symboles Pour chaque suppression, supprimez le nombre de symboles spécifié et enregistrez-les en tant que texte supprimé.
Commencez avec le texte final et traitez les modifications dans l'ordre inverse. Pour chaque , supprimez, insérez '?' symboles Pour chaque insérer, supprimez le nombre de symboles spécifié et enregistrez-les en tant que texte inséré.
Lorsque cela est terminé, tous vos « Insérer » et « Supprimer » les entrées de changement aura le texte associé au meilleur de nos connaissances, et tout texte qui a été inséré et immédiatement supprimé sera "? symboles
Pour obtenir la différence
Ceci est plus approprié pour marquer la révision ou la comparaison de version. Pour ces utilisations, utilisez simplement les informations de changement de texte pour calculer un ensemble de plages entières dans lesquelles des modifications peuvent être trouvées, puis utilisez un algorithme diff standard pour trouver les changements réels. Cela tend à être très efficace dans le traitement des changements incrémentiels, mais vous donne toujours les meilleures mises à jour. Ceci est particulièrement agréable lorsque vous collez un paragraphe de remplacement presque identique à l'original: l'utilisation des informations de changement de texte indiquera que tout le paragraphe est nouveau, mais en utilisant diff (c'est-à-dire cette technique) les courses qui sont réellement différentes.
Le code pour le calcul de la plage de modification est simple: Représentez la modification en quatre entiers (oldstart, oldend, newstart, newend). Courir à travers chaque changement:
- Si changeStart est avant newstart, réduire newstart à changeStart et réduire oldstart un montant égal
- Si changeEnd est après newend, augmenter newend à changeEnd et augmenter oldend un montant égal
Une fois cela fait, extraire la plage [oldstart, oldend] de l'ancien document et la plage [newstart, newend] du nouveau document, puis utiliser l'algorithme diff standard pour les comparer.
Où par "algorithme de diff standard", je suppose que nous pouvons utiliser [quelque chose comme le "google-diff-match-patch" .NET lib] (http://code.google.com/p/google-diff- match-patch /) - trouvé à partir de [cette question] (http://stackoverflow.com/questions/138331/any-decent-text-diff-merge-engine-for-net). – ruffin