如何解决使用递归计数双链接列表中的偶数元素
我有两个函数,一个是NumsEven(),另一个是NumsEvenHelper(Node * ptr),我有一个{2,4,5,10}列表,我应该使用递归来计算偶数,这就是我的想法到现在:
template <typename Data_t>
Data_t DLinkedList<Data_t>::NumEven() {
Node* ptr = _head;
return NumEvenHelper(ptr);
}
template <typename Data_t>
Data_t DLinkedList<Data_t>::NumEvenHelper(Node* ptr) {
ptr = _head;
if (empty()) return 0;
else if ((ptr->_data % 2 == 0))
return 1 + NumEvenHelper(ptr->_next);
}
解决方法
为了解决此问题,您可以添加两个成员函数:第一个成员函数是public,另一个是私有函数:
public:
std::size_t countEven() const noexcept;
private:
std::size_t countEven(Node *node) const noexcept;
双重链接列表的用户将使用第一个成员函数时,实际的递归/计算中将使用第二个成员函数。
std::size_t countEven() const noexcept {
return countEven(_head);
}
std::size_t countEven(Node *node) const noexcept {
if (nullptr != node) {
if (curr->_data % 2 == 0) {
return countEven(node->next) + 1; // since _data is even,increment by one
} else {
return countEven(node->next); // since _data is not even,don't increment
}
} else {
return 0; // in case we reach the end of list,we need to return starting value for counting
}
}
当然,蕴涵的是_data
成员是整数。
您实际上有两个 问题...这两个问题都可以通过简单的调试轻松发现。
第一个问题是您没有理由处理列表中的 odd 数据值。
如果ptr->_data
为奇数,则NumEvenHelper
函数将在不返回任何内容的情况下结束。这将导致未定义的行为,因为您的程序假定该函数将返回有效值。
该函数还将停止对奇数值的递归,因此即使您在列表中的后面有偶数值,也不会被计算在内。
简单的解决方案是简单地添加一个else
情况,您只需进行递归调用,而无需添加1
:
if (empty())
return 0;
else if ((ptr->_data % 2 == 0))
return 1 + NumEvenHelper(ptr->_next);
else // Is odd
return NumEvenHelper(ptr->_next);
第二个问题是您的助手函数总是设置ptr
指向_head
,而忽略了传递的参数。
这将导致对非空列表的无限递归,因为递归调用实际上将是:
NumEvenHelper(_head->_next);
您应该不在助手功能中具有该分配。
现在需要一点“技巧”(这将使您的代码难以阅读和理解)可以使您不必拥有if
,而不必担心else
:布尔结果(如比较结果)可以隐式转换为int
值,其中1
的{{1}}和true
的{{1}}。 / p>
这意味着您可以使用布尔条件作为部分或算术计算来代替0
或false
。
例如:
1
如果该值是偶数,则将0
添加到递归调用的结果中,否则它将添加if (empty())
return 0;
// No else here
return (ptr->_data % 2 == 0) + NumEvenHelper(ptr->_next);
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。