难以理解Paul Heckel的Diff算法

时间:2017-03-13 00:47:50

标签: python algorithm version-control file-diffs

我一直在关注Paul Heckel's Diff Algorithm而我似乎并没有完全理解它。

我复制了步骤1-5,如Python代码所示,但我无法通过算法的最后一步来显示差异。如果有人解释了Python代码的最后一步,我将不胜感激。

另外,我不完全理解为什么你需要在第4步和第5步中引用表格行,所以对此的解释也会很惊人!

非常感谢

这是我目前的代码:

def find_diff(current_file_as_list, different_file_as_list):

N = current_file_as_list
O = different_file_as_list

table = {}

OA = []
NA = []
for i in O:
    OA.append(i)
for i in N:
    NA.append(i)

# First pass
i = 0

for line in N:
    if not line in table:
        table[line] = {}
        table[line]["NC"] = 1
    else:
        if table[line]["NC"] == 1:
            table[line]["NC"] = 2
        else:
            table[line]["NC"] = "many"
    NA[i] = table[line]
    i += 1

# second pass
j = 0

for line in O:
    if not line in table:
        table[line] = {}
        table[line]["OC"] = 1
    else:
        if not "OC" in table[line]:
            table[line]["OC"] = 1
        elif table[line]["OC"] == 1:
            table[line]["OC"] = 2
        else:
            table[line]["OC"] = "many"
    table[line]["OLNO"] = j  # Gets overwritten with multiple occurrences.
    # Check to see if this is the intended implementation.
    # Maybe only relevant for "OC" == "NC" == 1
    OA[j] = table[line]
    j += 1

# third pass
i = 0

for i in range(0, len(NA)):
    # Check if they appear in both files
    if "OC" in NA[i] and "NC" in NA[i]:
        # Check if they appear exactly once
        if NA[i]["OC"] == NA[i]["NC"] == 1:
            olno = NA[i]["OLNO"]
            NA[i], OA[olno] = olno, i
    i += 1

# fourth pass
# ascending
for i in range(0, len(NA)):
    for j in range(0 , len(OA)):
        if NA[i] == OA[j] and i + 1 < len(NA) and j + 1 < len(OA) and NA[i + 1] == OA[j + 1]:
            OA[j + 1] = table[O[i + 1]]
            NA[i + 1] = table[N[j + 1]]

# fifth pass
# descending
for i in range(len(NA) - 1, 0, -1):
    for j in range(len(OA) - 1, 0, -1):
        if NA[i] == OA[j] and i - 1 > 0 and j - 1 > 0 and NA[i - 1] == OA[j - 1]:
            OA[j - 1] = table[O[i - 1]]
            NA[i - 1] = table[N[j - 1]]

# final step implementation should go here but I'm not sure how to approach it but this is my current attempt (which I am certain is wrong):
k = 0

array = []

for i in range(0, len(NA)):

    if isinstance(NA[i], int):
        array.append("= " + str(N[i]))
        k = NA[i] + 1
    elif isinstance(NA[i], dict):
        array.append("+ " + N[i])

    for j in range(k, len(OA)):
        k = j + 1
        print("j - " + str(j))
        if not isinstance(OA[j], int):
            array.append("- " + O[j])
        else:
            break

您可以将任意两个字符串或字符串列表作为输入传递给函数,例如。 find_diff(&#34;你好&#34;,&#34;地狱&#34;)

1 个答案:

答案 0 :(得分:4)

我不确定你在哪里找到这个解释和代码,但它有几个错误。用于数据比较的维基百科页面之一是a reference to Paul's paper,这对理解算法最有帮助。

首先,据我所知,您最后一步的实施是正确的(假设前面的步骤已正确完成)。

让我们从语法/语言问题开始:也许我错过了一些东西,但我不明白为什么你(和你链接到的代码)增加了自增量索引{ {3}}在第三次传递中。

关于表格条目的计数器:在链接的代码中有一个评论问题 - 为什么我们需要2个值?答案是 - 我们不要!在论文中,Heckel明确写道,计数器应该具有的唯一值是0,1和许多。您可以看到我们从不使用或查询计数器的2值。我疯狂地猜测这个错误来自于在编写算法时比Heckel想到的语言更灵活的语言实现算法,因为查询特定表条目的计数器是否存在与查询计数器是否同义#39; s值为0.

最后也是最重要的是,此实施中的第四和第五遍是错误的。在这里,我相信文章中的传递的措辞可能令人困惑,并且编写链接代码的人都错了。你的第二个问题已经揭晓了。第四遍是按i的升序排列,每个位置的值都指向NA中的位置(意味着它的类型为OA讨论了实现)我们检查两个数组中的下一个位置值是否指向同一个表项。如果他们这样做,我们将这些指针替换为彼此的位置(用int覆盖指针。所以你的第二个问题是关键 - 我们使用表这里的入口指针)。通过这种方式,我们在第三次传递中发现了我们独特的线条,作为锚点,可以找到紧跟在它们之后的未经改动的线条,并且是它们的一部分&#34;块#34;但在文件中并不是唯一的。同样的情况发生在第五遍,但是向后,所以在未改变的唯一线之前的相同线也将被归类为未改变的。

这是我描述的第四和第五遍:

int