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

时间:2018-10-18 21:29:57

标签: python python-3.x list 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

7 个答案:

答案 0 :(得分:2)

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

使用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)

答案 1 :(得分:1)

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)

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

重要的是要指出,如果两个列表都为空,则代码中缺少的基本情况是测试。

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

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

MsgBox DurationToSeconds("21:13:24")  'returns 76404

答案 4 :(得分:0)

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

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))

答案 5 :(得分: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)

答案 6 :(得分:0)

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

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