【问题标题】:Difficulty understanding Paul Heckel's Diff Algorithm难以理解 Paul Heckel 的 Diff 算法
【发布时间】:2017-08-02 23:04:46
【问题描述】:

我一直在看Paul Heckel's Diff Algorithm,但我似乎没有完全理解它。

我复制了 Python 代码中所示的步骤 1-5,但我无法使用算法的最后一步显示差异。如果有人解释最后一步以及 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("你好", "地狱")

【问题讨论】:

    标签: python algorithm version-control file-diffs


    【解决方案1】:

    我不确定您在哪里找到了这个解释和代码,但其中有几个错误。用于数据比较参考的 Wikipedia 页面之一是 a reference to Paul's paper,它被证明对理解算法最有帮助。

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

    让我们从语法/语言问题开始:也许我遗漏了一些东西,但我不明白为什么您(以及您链接到的代码)在第三遍中增加自增索引 i

    关于表条目的计数器:在链接代码中有一个注释问题 - 为什么我们需要 2 值?答案是——我们没有!在论文本身中,Heckel 明确写道,计数器应该具有的唯一值是 0、1 和 many。您可以看到我们从不使用或查询计数器的 2 值。我猜测这个错误来自于用一种比 Heckel 在编写算法时考虑的更灵活的语言来实现算法,因为查询特定表条目是否存在计数器与查询计数器是否存在同义值为 0。

    最后也是最重要的一点,这个实现中的第四和第五遍是错误的。在这里,我相信论文中通行证的措辞可能会令人困惑,并且编写链接代码的人都弄错了。你的第二个问题已经揭示了。第四遍是在NA 上按升序排列,对于每个位置,其值指向OA 中的位置(意味着它在讨论的实现中属于int 类型),我们检查是否两个数组中下一个位置的值指向同一个表条目。如果他们这样做,我们用彼此的位置替换这些指针(用ints 覆盖指针。所以你的第二个问题是正确的 - 我们在这里使用表条目指针)。这样,我们将在第三遍中发现的唯一行作为锚点,以查找紧随其后的未更改行,并且是其“块”的一部分,但在文件中不是唯一的。同样的情况发生在第五遍,但是倒过来,所以在未更改的唯一行之前的相同行也将被归类为未更改。

    这是我描述的第四次和第五次传球:

    # fourth pass
    # ascending
    for i in range(0, len(NA) - 1):
        if isinstance(NA[i], int) and (NA[i] + 1) < len(OA) and NA[i + 1] == OA[NA[i] + 1]:
            NA[i + 1] = NA[i] + 1
            OA[NA[i] + 1] = i + 1
    
    # fifth pass
    # descending
    for i in range(len(NA) - 1, 0, -1):
        if isinstance(NA[i], int) and (NA[i] - 1) >= 0 and NA[i - 1] == OA[NA[i] - 1]:
            NA[i - 1] = NA[i] - 1
            OA[NA[i] - 1] = i - 1
    

    【讨论】:

    • 谢谢。你的解释非常翔实。我期待看到更新的代码。关于第三步 3 中的语法/语言问题,我之前使用了类似于链接的字典,因此它用于保留对当前元素的引用,但是我稍后在实施过程中切换到列表正如您所说, i 的定义和增量是错误的。
    • 添加了代码。如果您发现任何不清楚或令人困惑的地方,请告诉我。
    • 如果这个答案是您要找的 - 请接受它作为正确答案(点击答案分数下方的勾号,在左侧)。
    • 嗨@et_l 这正是我想要实现的目标。谢谢你的帮助!我已经接受了这个作为答案
    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多