我想搜索链表中的值/字符,并返回值/字符在链表中的次数。如果我只使用递归而不是尾递归会更容易吗?
class MyList():
__slots__=('head','size')
class Empty():
__slots__=()
class NonEmpty():
__slots__=('data','next')
def mkMyList():
lst = MyList()
lst.head = mkEmpty()
lst.size = 0
return lst
def mkEmpty():
return Empty()
def mkNonEmpty(data,lst):
node = NonEmpty()
node.data = data
node.next = lst
return node
def count(l, value, c = 0):
l = mkMyList()
if l.head != value:
l.head = l.head.next
if l.head == value:
return count(l.head.next, value, c + 1)
if l.size == 0:
return c
当我尝试测试时,我明白了:
count(s,'s',c= 0)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
count(s,'s',c= 0)
File "C:\Users\Qasim\Desktop\Linked Lists.py", line 30, in count
l.head = l.head.next
AttributeError: 'Empty' object has no attribute 'next'
\
答案 0 :(得分:1)
我会使用迭代器模式,而不是使用递归。这是在您的问题的上下文中执行此操作的一种方法:
class LinkedList(object):
class Node(object):
__slots__ = ('prev', 'next', 'value')
def __init__(self, prev=None, next=None, value=None):
self.prev = prev
self.next = next
self.value = value
def __init__(self, iterable=[]):
self.head = LinkedList.Node() # dummy node
self.tail = self.head
self.size = 0
for item in iterable:
self.append(item)
def __iter__(self):
current = self.head
while True:
if current.next is not None:
current = current.next
yield current.value
else:
raise StopIteration
def append(self, value):
self.tail.next = LinkedList.Node(prev=self.tail, value=value)
self.tail = self.tail.next
self.size += 1
def pop(self):
if self.size > 0:
value = self.tail.value
self.tail = self.tail.prev
self.tail.next = None
self.size -= 1
return value
else:
raise IndexError('pop from empty list')
def count(self, value):
cumsum = 0
for item in self:
if item == value:
cumsum += 1
return cumsum
通过我定义Python special method __iter__
,可以按以下方式依次访问LinkedList
的元素:
l = LinkedList([1, 2, 3, 3, 3, 4, 5])
for value in l:
print(value)
然后直接实现所需的方法count
。
请注意,我使用Python生成器语法来实现__iter__
,您可以阅读有关生成器和yield
语句here的内容。
答案 1 :(得分:0)
跟踪您的代码:
l = mkMyList() # => head = Empty()
if l.head != value: # True since head is Empty()
l.head = l.head.next # Empty does not have a ".next" attribute
这是Traceback告诉你的。
编辑:还有两件事:(1)我不确定为什么count甚至在调用mkMyList时,你的意图似乎是将它传递给函数args中的列表l。 (2)我猜你想把size-check if语句放在这个函数的顶部:if l.size == 0:
return c
答案 2 :(得分:0)
我看到的问题是count
中的列表从未正确初始化。在mkMyList()
中,head
元素设置为Empty
,其中没有next
属性。在count()
中,您只能使用mkMyList()
。这意味着l.head
是Empty
,并且它无法拥有next
属性。要解决此问题,我建议使用给定的输入实例化列表l
。
关于递归的问题:不,在组成尾递归函数和常规递归函数方面差别很小。