차이 알고리즘? [닫은]
작동하고 효율적인 diff 알고리즘에 대한 설명이 미친 것처럼 보였습니다.
내가 얻은 가장 가까운 것은 RFC 3284 (여러 Eric Sink 블로그 게시물에서)에 대한 링크 입니다. 이 링크 는 diff 결과가 저장되는 데이터 형식 을 완벽하게 이해할 수있는 용어로 설명 합니다. 그러나 diff를 수행하는 동안 프로그램이 이러한 결과에 도달하는 방법에 대해서는 언급하지 않았습니다.
diff 알고리즘을 구현할 때 절충이 있어야한다고 확신하기 때문에 개인적 호기심에서 이것을 연구하려고합니다. diff 알고리즘을 볼 때 종종 분명하고 diff 프로그램이 왜 이것을 diff로 선택했는지 궁금합니다. 그것 대신에?"...
VCDIFF를 출력하는 효율적인 알고리즘에 대한 설명은 어디에서 찾을 수 있습니까?
그런데 SourceGear의 DiffMerge에서 사용하는 실제 알고리즘에 대한 설명을 찾으면 훨씬 좋습니다.
참고 : 가장 긴 공통 하위 시퀀스는 VCDIFF에서 사용하는 알고리즘이 아닌 것처럼 보입니다. 사용하는 데이터 형식에 따라 더 똑똑한 것으로 보입니다.
O (ND) 차이 알고리즘과 그 변형 은 훌륭한 논문이므로 여기서 시작할 수 있습니다. 여기에는 의사 코드와 diff 수행과 관련된 그래프 순회에 대한 멋진 시각화가 포함됩니다.
이 논문의 섹션 4 는 알고리즘을 개선하여 매우 효과적으로 개선하는 방법을 소개합니다.
이것을 성공적으로 구현하면 도구 상자에 매우 유용한 도구가 있습니다 (아마도 훌륭한 경험이 될 것입니다).
필요한 출력 형식을 생성하는 것은 때때로 까다로울 수 있지만 알고리즘 내부를 이해하고 있으면 필요한 것을 출력 할 수 있어야합니다. 휴리스틱을 도입하여 출력에 영향을 미치고 특정 상충 관계를 만들 수도 있습니다.
다음은 위에서 언급 한 알고리즘의 기술을 사용하여 약간의 문서, 전체 소스 코드 및 diff 알고리즘의 예 를 포함 하는 페이지 입니다 .
소스 코드가 밀접하게 기본 알고리즘을 따르도록 표시하고 읽기 쉽다.
입력 준비에 약간의 도움이 될 수도 있습니다. 문자 나 토큰 (단어)으로 구분할 때 출력에 큰 차이가 있습니다.
행운을 빕니다!
GNU에서 사용할 수 있는 diff 의 실제 소스 코드 를 살펴 보는 것부터 시작하겠습니다 .
해당 소스 코드가 실제로 어떻게 작동하는지 이해하기 위해 해당 패키지의 문서는 소스 코드에서 영감을 얻은 논문을 참조합니다.
기본 알고리즘은 "O (ND) 차이 알고리즘 및 그 변형", Eugene W. Myers, 'Algorithmica'Vol. 1 No. 2, 1986, pp. 251-266; "파일 비교 프로그램"에서 Webb Miller와 Eugene W. Myers, 'Software--Practice and Experience'Vol. 15 No. 11, 1985, 1025-1040 쪽. 알고리즘은 "근사 문자열 매칭 알고리즘", E. Ukkonen,`Information and Control 'Vol. 64, 1985, 100-118 쪽.
논문을 읽고 구현을위한 소스 코드를 살펴보면 작동 방식을 이해하기에 충분해야합니다.
https://github.com/google/diff-match-patch를 참조 하십시오
"Diff Match 및 Patch 라이브러리는 일반 텍스트 동기화에 필요한 작업을 수행하는 강력한 알고리즘을 제공합니다. ... 현재 Java, JavaScript, C ++, C # 및 Python에서 사용 가능"
또한 wikipedia.org Diff 페이지 와 " Bram Cohen : diff 문제가 해결되었습니다 "를 참조하십시오.
diff 알고리즘을 찾고 여기에 와서 나만의 구현을했습니다. vcdiff에 대해 모르겠습니다.
위키 백과 : 가장 긴 공통 서브 시퀀스에서 diff-like 출력을 얻는 작은 단계 일뿐입니다. 서브 시퀀스에 항목이 없지만 원래 항목에 있으면 항목을 삭제해야합니다. (아래의 '–'표시) 하위 시퀀스에는 없지만 두 번째 시퀀스에있는 경우 추가해야합니다 ( '+'표시).
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가 제공 한 링크를 기반으로 Neil Fraser 웹 사이트 (도서관의 저자 중 하나) 에 Diff Strategies 가 많이 있습니다 .
그는 기본 전략을 다루고 기사 끝까지 Myer의 알고리즘과 일부 그래프 이론으로 진행합니다.
참고 URL : https://stackoverflow.com/questions/805626/diff-algorithm
'IT박스' 카테고리의 다른 글
Java에서 XML을 JSON으로 변환하는 가장 빠른 방법 (0) | 2020.06.02 |
---|---|
제네릭 형식 매개 변수를 문서화하기위한 javadoc 태그가 있습니까? (0) | 2020.06.02 |
모든 gcc 경고 비활성화 (0) | 2020.06.02 |
extern 키워드가 C 함수에 미치는 영향 (0) | 2020.06.02 |
Angularjs 코드 / 이름 지정 규칙 (0) | 2020.06.02 |