문제

나는 작동하고 효율적인 Diff 알고리즘에 대한 설명에 미친 것처럼 보였다.

내가 가장 가까운 것은입니다 이 RFC 3284에 대한 링크 완벽하게 이해할 수있는 용어로 설명하는 (여러 Eric 싱크 블로그 게시물) 데이터 형식 Diff 결과가 저장됩니다. 그러나 프로그램이 어떻게 이러한 결과에 도달 할 것인지에 대한 언급은 없습니다.

나는 Diff 알고리즘을 구현할 때 트레이드 오프가 있어야한다고 확신하기 때문에 개인적인 호기심에서 이것을 연구하려고 노력하고 있습니다. Diffs를 보았을 때 때때로 분명합니다. "Diff 프로그램이 왜 이것을 변화로 선택했는지 궁금해합니다. 그것 대신에?"...

VCDIFF를 출력하게되는 효율적인 알고리즘에 대한 설명은 어디에서 찾을 수 있습니까?
그건 그렇고, SourceGear의 Diffmerge가 사용하는 실제 알고리즘에 대한 설명을 찾으면 더 나을 것입니다.

참고 : 가장 긴 공통 후속은 VCDIFF에서 사용하는 알고리즘 인 것 같습니다. 그들이 사용하는 데이터 형식을 감안할 때 더 똑똑한 일을하는 것처럼 보입니다.

도움이 되었습니까?

해결책

O (ND) 차이 알고리즘 및 변형 환상적인 종이이며 거기서 시작하고 싶을 수도 있습니다. 여기에는 의사 코드와 Diff 수행과 관련된 그래프 트래버스의 멋진 시각화가 포함됩니다.

섹션 4 이 논문은 알고리즘에 매우 효과적인 몇 가지 개선을 소개합니다.

이를 성공적으로 구현하면 도구 상자에 매우 유용한 도구가 생길 수 있습니다 (아마도 훌륭한 경험도있을 것입니다).

필요한 출력 형식을 생성하면 때때로 까다로울 수 있지만 알고리즘 내부를 이해하면 필요한 모든 것을 출력 할 수 있어야합니다. 또한 출력에 영향을 미치고 특정 트레이드 오프를하기 위해 휴리스틱을 소개 할 수도 있습니다.

여기에 페이지가 있습니다 여기에는 약간의 문서가 포함되어 있습니다. 전체 소스 코드, 앞서 언급 한 알고리즘의 기술을 사용한 Diff 알고리즘의 예.

그만큼 소스 코드 기본 알고리즘을 면밀히 따르는 것으로 보이며 읽기 쉽습니다.

입력을 준비하는 데 약간도 유용 할 수 있습니다. 문자 또는 토큰 (단어)별로 차이가있을 때 출력에는 큰 차이가 있습니다.

행운을 빕니다!

다른 팁

나는 실제를 보면서 시작할 것입니다 소스 코드 GNU가 만드는 Diff의 경우 사용 가능.

용을 위해 이해 해당 소스 코드가 실제로 어떻게 작동하는지에 대해 해당 패키지의 문서는 영감을 준 논문을 참조합니다.

기본 알고리즘은 "O (ND) 차이 알고리즘 및 그 변형", Eugene W. Myers, 'Algorithmica'Vol. 1 No. 2, 1986, 251-266 쪽; "파일 비교 프로그램"에서 Webb Miller와 Eugene W. Myers, '소프트웨어-연습 및 경험'Vol. 15 No. 11, 1985, pp. 1025-1040. 이 알고리즘은 "대략적인 문자열 일치에 대한 알고리즘", E. UKKONEN,`Information and Control 'Vol. 64, 1985, pp. 100-118.

논문을 읽은 다음 구현을위한 소스 코드를 살펴보면 작동 방식을 이해하기에 충분해야합니다.

보다 https://github.com/google/diff-match-patch

"Diff Match 및 Patch Libraries는 일반 텍스트 동기화에 필요한 작업을 수행하는 강력한 알고리즘을 제공합니다. 현재 Java, JavaScript, C ++, C# 및 Python에서 사용할 수 있습니다."

또한 참조하십시오 wikipedia.org diff 페이지 그리고 - "Bram Cohen : Diff 문제가 해결되었습니다"

나는 Diff 알고리즘을 찾아 여기에 와서 나중에 내 자신의 구현을했다. vcdiff에 대해 모른다.

위키 백과: 가장 긴 공통 후속에서는 차이와 같은 출력을 얻는 작은 단계 일뿐입니다. 항목이 후속에 없지만 원본에 존재하는 경우 삭제해야합니다. ( ' -'marks, 아래.) 후속에 없지만 두 번째 시퀀스에 존재하는 경우 ( '+'마크.) 추가되어야합니다.

멋진 애니메이션 LCS 알고리즘은 여기에 있습니다.

금식 링크 LCS 루비 구현.

느리고 간단한 루비 적응은 다음과 같습니다.

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]

Emmelaich가 제공 한 링크를 바탕으로 Diff 전략이 많이 있습니다. Neil Fraser의 웹 사이트 (도서관의 저자 중 하나).

그는 기본 전략을 다루고 기사의 끝을 향해 Myer의 알고리즘과 일부 그래프 이론으로 진행됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top