繁体   English   中英

使用递归检查两个未排序列表的元素和长度是否相等

[英]Check if the elements and length of two unsorted lists are equal using recursion

我正在尝试编写一个纯递归函数,如果两个未排序的列表长度相同且包含相同的元素,则该函数将返回True。 我不允许使用任何迭代,只能使用递归。 以下是应执行的操作示例:

>>> SameStuff(['Hello',1,2,3],[3,2,1,'Hello'])
True
>>> SameStuff(['HELLO',1,2,3],[3,'two',1,'Hello'])
False
>>> SameStuff([1,2],[])
False

我为递归函数的逻辑而苦苦挣扎,并且缺少一些要素。 这是我所拥有的:

def SameStuff(list1,list2):
    if len(list1)!=len(list2):
        return False
    if #some base case:
        #return True?
    if list1[0] in list2:
        return SameStuff(list1[1:],list2)
    else:
        return False

我认为您将大多数逻辑放在正确的位置。 您只是错过了两个都为空的情况,到那时,它们可能是相同的列表,但顺序不同(可能)!

使用remove函数可能效率不高,但是要从两个不同的无序列表中弹出相同的元素会比较棘手。

def SameStuff(l1, l2):
    if not l1 and not l2:
        return True

    if len(l1) != len(l2):
        return False

    last_element = l1[-1]
    if last_element not in l2:
        return False

    l1.remove(last_element)
    l2.remove(last_element)

    return SameStuff(l1, l2)
def SameStuff(list1, list2):

    # if both empty, they are equal
    if not list1 and not list2:
        return True

    # if unequal lengths, they are not equal
    if len(list1) != len(list2):
        return False

    # grab the first item from list1
    item = list1[0]

    # if it isn't in list2, they are not equal
    if item not in list2:
        return False

    # make copies so we don't disturb the original lists
    newlist1 = list1[:]
    newlist2 = list2[:]

    # remove the item from both copies
    newlist1.remove(item)
    newlist2.remove(item)

    # call ourself with the list copies
    return SameStuff(newlist1, newlist2)
def SameStuff(l1, l2):
    if l1 == []: return l2 == []    # if recursed down to empty lists -> True
    elif len(l1) != len(l2): return False   # if any length differences -> False
    elif l1[0] in l2: 
        i = l2.index(l1[0]) # identify index of first in l2 identical to l1[0]
        return SameStuff(l1[1:], l2[:i] + l2[i+1:]) # l2 without this element!
    else: return False

这与订单无关。 以及某些元素是否多次出现。

重要的是要声明,如果两个列表都为空,则代码中缺少的基本案例是test。

另一个重要因素是避免从两个已接收列表中的任何一个中删除找到的元素,因为这可能在调用后更改它们。

这是与您的代码相同的代码,我认为修改最少:

def SameStuff(list1,list2):                                                   
    if len(list1)!=len(list2):
        return False
    if len(list1) == 0 and len(list2) == 0:
        return True
    if list1[0] in list2:
        list2b = list2[:]
        list2b.remove(list1[0])
        return SameStuff(list1[1:], list2b)
    else:
        return False


print(SameStuff(['Hello',1,2,3], [3,2,1,'Hello']))
print(SameStuff(['HELLO',1,2,3],[3,'two',1,'Hello']))
print(SameStuff([1,2],[]))

为了不造成任何循环,您可以在函数的输入中添加一个参数:

def SameStuff(list1,list2,i):
    if list1==[] and list2==[]:
        return True

    elif i>=len(list1):
        return False

    elif len(list1)!=len(list2):
        return False

    elif list1[i]==list2[0]:
        del list1[i]
        del list2[0]
        return SameStuff(list1,list2,0)
    else:
        return SameStuff(list1,list2,i+1)


print(SameStuff(["hello",1,4],[1,3,"hello"],0))
print(SameStuff(["hello",1,3],[1,3,"hello"],0))
def SameStuff(l1, l2):
    if l1 and l2:  # both contain something
        try:
            index = l2.index(l1[0])

            return SameStuff(l1[1:], l2[:index] + l2[1 + index:])  # recurse

        except ValueError:

            return False  # a value in one wasn't found in the other

    return not(l1 or l2)  # only one contains something (False), or neither do (True)

另一个想法是再插入三个默认参数(第一个函数调用不需要这些默认参数):空字典,整数索引和布尔值。

使用布尔值指示要遍历的列表,并使用索引指向当前列表元素(我们也可以在索引上使用符号而不是布尔值)。 当遍历第一个列表时,使用元素作为键在字典中记录遇到的每个唯一元素的计数。 最后,翻转布尔值并遍历第二个列表,这次从字典中的元素计数中减去。 删除所有达到零计数的元素。 假设我们已经测试了匹配列表的长度,如果在字典中找不到元素,则列表不匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM