递归编程需要什么代码?

时间:2017-04-18 06:16:23

标签: python function recursion sequence computer-science

目前我在CS的离散结构类中,我们在Python中进行编程分配以研究递归。他给了我们三个模块,他希望我们实现代码,以使函数给出一个True或False变量。这是他的代码:

class WrongTypeArgumentException( Exception ): pass

def car(lst):
    """
    The first of the 3 primitive functions: return the first element of a 
    sequence. 

    .. note:: The Law of Car: The `car` function is only defined for non-empty lists.

    :param lst: a non-empty sequence; passing an empty sequence will raise an exception.
    :type lst: tuple
    :returns: an object
    :rtype: object
    """
    if type(lst) is not tuple: 
        raise WrongTypeArgumentException("Argument is not a list.")
    if len(lst)==0:
        raise WrongTypeArgumentException("List has no element") 
    if len(lst)>=1:
        return lst[0]

def cdr( lst ):
    """ The second of the 3 primitive functions: return a sequence, minus the first element.

    .. note:: The Law of Cdr: The `cdr` function is only defined for non-empty lists; the `cdr` of any non-empty list is always another list.


    :param lst: a non-empty sequence; passing an empty sequence will raise an exception.
    :type lst: tuple
    :returns: a tuple; if the sequence has only one element, return an empty sequence.
    :rtype: tuple
    """
    if type(lst) is not tuple:
        raise WrongTypeArgumentException("Argument is not a list.")
    if len(lst)==0:
        raise WrongTypeArgumentException("Cannot cdr on an empty list.")
    if len(lst)==1:
        return ()
    return lst[1:]

def cons( a, lst):
""" The third of the 3 primitive functions: return the sequence created by 
adding element `a` to the sequence `lst`.

.. note:: The Law of Cons: the primitive `cons` takes two arguments; the 
second argument to `cons` must be a list; the result is a list.

:param a: an object
:param lst: a tuple
:type a: object
:type lst: tuple
:returns: the tuple resulting from adding parameter `a` in front of sequence 
`lst`.
:rtype: tuple
"""
if type(lst) is not tuple:
    raise WrongTypeArgumentException("Argument is not a list.")
return (a,) + lst



def copy_sequence( seq ):
    """ Return the copy of a sequence, recursively.

    :param seq: the sequence to be copied
    :type seq: tuple
    :returns: a tuple, identical to the sequence that has been passed in
    :rtype: tuple
    """ 
    if seq == ():
        return ()
    print('seq={} CONSing {} to copy_sequence( {} )'.format(seq, car(seq), 
    cdr(seq)))
    return cons( car(seq), copy_sequence( cdr( seq) ))

def reverse_sequence( seq ):
    """ Return a sequence, in the reverse order, recursively.

    :param seq: the sequence to be reversed.
    :type seq: tuple
    :returns: a tuple, with the same elements, in the reverse order.
    :rtype: tuple
    """ 

    ## A function in a function (= inner function), that recursively accumulates
    ## elements in the bag
    def reverse_sequence_recursive( seq, bag):

        if seq == ():
            return bag
        return reverse_sequence_recursive( cdr(seq), cons(car(seq), bag))

    # Calling the inner function, with an empty bag to start with   
    return reverse_sequence_recursive( seq, () )

以下是我们应该实现的代码:

def count_sequence( seq ):
    """ Count the elements in a sequence, recursively. PROVIDE AN IMPLEMENTATION (TASK #1). This function should use **car** and **cdr**.

    :param seq: the sequence whose elements are to be counted
    :type seq: tuple
    :returns: the numbers of elements in the sequence
    :rtype: int
    """ 

def search_sequence( seq, item ):
    """ Search a sequence for the given item. PROVIDE AN IMPLEMENTATION (TASK 
    #2). This function should use **car** and **cdr**.

    :param seq: the sequence to be searched.
    :param item: the item to be searched
    :type seq: tuple
    :type item: str
    :returns: True if the item is contained in the sequence, False otherwise.
    :rtype: bool
    """ 
    ## YOUR CODE HERE #1. Base Case 2. Recursive Call 3. RC steps toward the 
    base case.  
    pass

最后,这里是他给出的测试函数,以便实际测试我们的代码是否正确。

class PyLisp_unittest( unittest.TestCase ):
    sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", 
    "cheese")

    def test_copy_sequence_0(self):
        """ Read empty tuple """
        sandwich = ()
        self.assertEqual( copy_sequence( sandwich ), ())

    def test_copy_sequence_1(self):
        """ Read single-element tuple"""
        sandwich = ('mustard',)
        self.assertEqual( copy_sequence( sandwich ), ('mustard',))

    def test_copy_sequence_2(self):
        """ Read 7-element tuple"""
        sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", "cheese")
        self.assertEqual( copy_sequence( sandwich ), sandwich)


    def test_reverse_sequence_0(self):
        """ Reverse empty tuple """
        sandwich = ()
        self.assertEqual( reverse_sequence( sandwich ), ())

    def test_reverse_sequence_1(self):
        """ Reverse single-element tuple"""
        sandwich = ('mustard',)
        self.assertEqual( reverse_sequence( sandwich ), ('mustard',))

    def test_reverse_sequence_2(self):
        """ Reverse 7-element tuple"""
        sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", "cheese")
        self.assertEqual( reverse_sequence( sandwich ), sandwich[::-1])

    def test_count_sequence_0(self):
        """ Count empty tuple """
        sandwich = ()
        self.assertEqual( count_sequence( sandwich ), 0)

    def test_count_sequence_1(self):
        """ Count single-element tuple"""
        sandwich = ('mustard',)
        self.assertEqual( count_sequence( sandwich ), 1)

    def test_count_sequence_2(self):
        """ Count 7-element tuple"""
        sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", "cheese")
        self.assertEqual( count_sequence( sandwich ), 7)

    def test_search_sequence_0(self):
        """ Search empty tuple """
        sandwich = ()
        self.assertEqual( search_sequence( sandwich, 'ham' ), False)

    def test_search_sequence_size_1_1(self):
        """ Search  single-element tuple: successful search"""
        sandwich = ('mustard',)
        self.assertEqual( search_sequence( sandwich, 'mustard' ), True)

    def test_search_sequence_size_1_2(self):
        """ Search single-element tuple: unsuccessful search"""
        sandwich = ('mustard',)
        self.assertEqual( search_sequence( sandwich, 'ham' ), False)

    def test_search_sequence_size_7_1(self):
        """ Search 7-element tuple: successful search"""
        sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", 
        "cheese")
        self.assertEqual( search_sequence( sandwich, 'pickles'), True)

    def test_search_sequence_size_7_2(self):
        """ Search 7-element tuple: unsuccessful search"""
        sandwich = ("jelly","butter", "mustard", "bread", "pickles", "jam", 
        "cheese")
        self.assertEqual( search_sequence( sandwich, 'pear'), False)

他没有就这些材料发表任何演讲,没有人百分百肯定该做什么。我尝试过与同伴导师见面,他并没有真正给予太多帮助,只重新开始了教科书对序列的定义,而不是如何实现代码。所以我想我问的是代码是什么样的。我需要将哪些内容添加到count_sequence(seq)search_sequence(seq, item):函数中。谢谢!!!

1 个答案:

答案 0 :(得分:0)

你被要求实施的是微不足道的,所以不要惊慌。

count_sequence(seq)

这两者中更容易。如果seq为空,则返回零。您将在教师的其他功能中找到的示例测试,例如copy_sequence()

如果seq不为空,则返回1加上在count_sequence()的尾部(cdr())递归调用seq的结果。那就是它。

这可以使用一个if语句来实现,该语句中包含return语句,其中包含两种情况之一。 if语句后面会跟一个涵盖另一个案例的return语句。

search_sequence(seq, item)

这只是稍微多一点的代码。如果seq为空,则此时返回False,因为它是布尔(谓词)函数。如果它不为空,请将itemcar()的第一项(seq)进行比较。如果它们相同,请返回True

否则,返回在同一search_sequence()上递归调用itemcdr()的余数(seq)的结果。这种递归呼叫的真实性或错误性就是答案,你不需要检查它,只需将其归还。

这里有三种情况,所以这可以使用两个if语句实现,每个语句返回一个值,最后return语句覆盖第三种情况。