Algorytm Diff? [zamknięte]

Wyglądałem jak szalony dla wyjaśnienia algorytmu diff, który działa i jest skuteczny.

Najbliżej jest ten link do RFC 3284 (z kilku postów na blogu Erica Sinka), który opisuje w całkowicie zrozumiały sposób format danych , w którym przechowywane są wyniki różnic. Jednak nie ma żadnej wzmianki o tym, jak program osiągnie te wyniki podczas robienia różnic.

Staram się to zbadać z osobistej ciekawości, ponieważ Jestem pewien, że muszą być kompromisy podczas wdrażania algorytmu diff, które są dość jasne czasami, gdy patrzysz na diff i zastanawiasz się "dlaczego program diff wybrał to jako zmianę zamiast tego?"...

Gdzie mogę znaleźć opis wydajnego algorytmu, który skończyłby na wyprowadzeniu VCDIFF?
Przy okazji, jeśli zdarzy ci się znaleźć opis rzeczywistego algorytmu używanego przez SourceGear ' s DiffMerge, byłoby jeszcze lepiej.

Uwaga: najdłuższa wspólna podróż nie wydaje się aby być algorytmem używanym przez VCDIFF, wygląda na to, że robią coś mądrzejszego, biorąc pod uwagę format danych, którego używają.

Author: Cœur, 2009-04-30

5 answers

Algorytm różnicy O (ND) i jego odmiany jest fantastycznym artykułem i możesz zacząć od niego. Zawiera pseudo-kod i ładną wizualizację grafów zaangażowanych w Robienie różnic.

Sekcja 4 artykułu wprowadza pewne udoskonalenia algorytmu, które czynią go bardzo skutecznym.

Pomyślne wdrożenie tego pozostawi cię z bardzo przydatnym narzędziem w zestawie narzędzi (i prawdopodobnie jakieś doskonałe doświadczenie jako cóż).

Generowanie potrzebnego formatu wyjściowego może być czasami trudne, ale jeśli masz zrozumienie wewnętrznych algorytmów, powinieneś być w stanie uzyskać wszystko, czego potrzebujesz. Można również wprowadzić heurystykę, aby wpłynąć na wynik i dokonać pewnych kompromisów.

Poniżej znajduje się Strona, która zawiera trochę dokumentacji, Pełny kod źródłowy oraz przykłady algorytmu diff wykorzystującego techniki wspomnianego algorytmu.

Źródło kod wydaje się być ściśle zgodny z podstawowym algorytmem i jest łatwy do odczytania.

Jest też trochę na temat przygotowania danych wejściowych, które mogą okazać się przydatne. Istnieje ogromna różnica w wydajności, gdy różni się znak lub token (słowo).

Powodzenia!

 149
Author: jscharf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-21 17:23:00

Zacząłbym od spojrzenia na rzeczywisty kod źródłowy dla Diffa, który GNU udostępnia .

Dla zrozumienia Jak działa ten kod źródłowy, dokumenty w tym pakiecie odwołują się do dokumentów, które go zainspirowały:

Podstawowy algorytm jest opisany w" An O(ND) Difference Algorithm and its Variations", Eugene W. Myers, "Algorithmica" Vol. 1 Nr 2, 1986, s. 251-266; oraz w " pliku Comparison Program", Webb Miller i Eugene W. Myers, "Software--Practice and Experience" Vol. 15-11-1985, S. 1025-1040. Algorytm został niezależnie odkryty, jak opisano w "Algorithms for Approximate String Matching", E. Ukkonen, "Information and Control" Vol. 64, 1985, s. 100-118.

Przeczytanie dokumentów, a następnie spojrzenie na kod źródłowy implementacji powinno wystarczyć, aby zrozumieć, jak to działa.

 31
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-30 23:23:04

Zobacz http://code.google.com/p/google-diff-match-patch/

" Biblioteki różnic i poprawek oferują solidne algorytmy do wykonywania operacje wymagane do synchronizacji zwykły tekst. ... Aktualnie dostępne w Javie, JavaScript, C++, C# i Python "

Zobacz też wikipedia.org strona Diff i - "Bram Cohen: problem diff został rozwiązany "

 27
Author: Matthew Hannigan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-22 14:39:01

Przyszedłem tu w poszukiwaniu algorytmu diff, a potem zrobiłem własną implementację. Przepraszam, że nie wiem o vcdiff.

Wikipedia: z najdłuższej wspólnej sekwencji jest to tylko mały krok, aby uzyskać wynik podobny do Diffa: jeśli element jest nieobecny w subsequence, ale obecny w oryginale, musiał zostać usunięty. (Znaki"–", poniżej.), Jeśli nie występuje w dalszej kolejności, ale występuje w drugiej kolejności, musi być dodany w. (Znaki"+".)

Nice animacja algorytmu LCS tutaj .

Link do szybkiej implementacji LCS ruby tutaj .

Moja powolna i prosta adaptacja ruby jest poniżej.

def lcs(xs, ys)
  if xs.count > 0 and ys.count > 0
    xe, *xb = xs
    ye, *yb = ys
    if xe == ye
      return [xe] + lcs(xb, yb)
    end
    a = lcs(xs, yb)
    b = lcs(xb, ys)
    return (a.length > b.length) ? a : b
  end
  return []
end

def find_diffs(original, modified, subsequence)
  result = []
  while subsequence.length > 0
    sfirst, *subsequence = subsequence
    while modified.length > 0
      mfirst, *modified = modified
      break if mfirst == sfirst
      result << "+#{mfirst}"
    end
    while original.length > 0
      ofirst, *original = original
      break if ofirst == sfirst
      result << "-#{ofirst}"
    end
    result << "#{sfirst}"
  end
  while modified.length > 0
    mfirst, *modified = modified
    result << "+#{mfirst}"
  end
  while original.length > 0
    ofirst, *original = original
    result << "-#{ofirst}"
  end
  return result
end

def pretty_diff(original, modified)
  subsequence = lcs(modified, original)
  diffs = find_diffs(original, modified, subsequence)

  puts 'ORIG      [' + original.join(', ') + ']'
  puts 'MODIFIED  [' + modified.join(', ') + ']'
  puts 'LCS       [' + subsequence.join(', ') + ']'
  puts 'DIFFS     [' + diffs.join(', ') + ']'
end

pretty_diff("human".scan(/./), "chimpanzee".scan(/./))
# ORIG      [h, u, m, a, n]
# MODIFIED  [c, h, i, m, p, a, n, z, e, e]
# LCS       [h, m, a, n]
# DIFFS     [+c, h, +i, -u, m, +p, a, n, +z, +e, +e]
 9
Author: neoneye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-29 04:26:55

Bazując na linku podanym przez Emmelaich, na stronie internetowej Neila Frasera (jednego z autorów biblioteki) znajduje się również wiele różnych strategii.

Omawia podstawowe strategie i pod koniec artykułu przechodzi do algorytmu Myera i teorii grafów.

 7
Author: Chris S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-08 09:28:55