【问题标题】:Merge Sort 2 Lists Finding Common Elements合并排序 2 列表查找共同元素
【发布时间】:2015-08-19 06:35:27
【问题描述】:

对于一项作业,我们被要求编写一个函数,该函数将 2 个列表作为输入,然后返回一个列表,其中包含“列表 1”和“列表 2”中的所有名称。

已要求使用基于合并排序的算法来完成。到目前为止我得到的返回正确的列表,但是我进行了太多的比较来获得这个列表。 VoterList 是提供给我们的指定类,因此我们不使用普通的 python 列表。只有 VoterName 对象(两个输入列表的组成)能够附加到 VoterList。传入的列表都按字典顺序排列。

欢迎任何关于如何减少我的比较的建议。谢谢。

from classes import VoterList
def fraud_detect_merge(first_booth_voters, second_booth_voters):

    fraud = VoterList()
    length_first = len(first_booth_voters)
    length_second = len(second_booth_voters)
    first_booth_position = 0
    second_booth_position = 0
    comparisons = 0
    while first_booth_position < length_first:

        if second_booth_position == length_second:
            first_booth_position += 1
            second_booth_position = 0

        else:
            name_comparison = first_booth_voters[first_booth_position]
            comparisons += 1

            if second_booth_voters[second_booth_position] == name_comparison:
                fraud.append(second_booth_voters[second_booth_position])
                first_booth_position += 1
                second_booth_position = 0

            else:
                second_booth_position += 1


    return fraud, comparisons

【问题讨论】:

    标签: python list python-3.x merge mergesort


    【解决方案1】:

    不清楚你的输入是什么,它已经排序了吗?您正在获得列表。查看可以对列表执行哪些操作,您会发现pop() 操作。这将从列表中删除一项并为您提供其值。由于列表都是按顺序排列的,因此可以使用以下方法:

    def fraud_detect_merge(first_booth_voters, second_booth_voters):
        fraud = VoterList()
        comparisons = 0
    
        first_booth_voters.sort()     # if not already sorted
        second_booth_voters.sort()    # if not already sorted
    
        first = first_booth_voters[0]
        second = second_booth_voters[0]
    
        while first_booth_voters and second_booth_voters:
            comparisons += 1
    
            if first == second:
                fraud.append(first)
                first = first_booth_voters.pop(0)
                second = second_booth_voters.pop(0)
            elif first < second:
                first = first_booth_voters.pop(0)
            else:
                second = second_booth_voters.pop(0)
    
        return fraud, comparisons
    

    【讨论】:

    • 非常感谢。这很有帮助。没有按照你的确切方式做,但它启发了另一个:)
    • 嘿,有没有机会和你一起跳进聊天室?谢谢:)
    【解决方案2】:

    作业要求找到一个解决方案,并且有合并排序的重要提示,所以我不会为你泄露答案:) 但也许我可以指出您的代码中发生了什么:在您的 while 循环中,在最坏的情况下,您基本上完成了两个长度为 length_firstlength_second 的嵌套循环:

    for name_comparison in first_booth_voters:
      for second_name in second_booth_voters:
        comparisons += 1
        if second_name == name_comparison:
          fraud.append(second_name)
          break
    

    这导致在最坏的情况下进行length_first x length_second 比较。鉴于输入列表已排序,这当然不是最优的。您需要利用排序的优势。如果输入列表没有排序,你应该考虑用更易读的嵌套 for 循环替换你更难阅读/调试/理解的 while 循环。

    【讨论】:

    • 是的,谢谢。我在发帖后不久就意识到了这一点。我现在找到了一个可行的替代方案。谢谢
    猜你喜欢
    • 2018-04-29
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    相关资源
    最近更新 更多