以下是合并k排序列表的c ++代码。但我很困惑阅读前4行代码。我知道它的作用只是混淆了它是如何做到的。有人可以向我解释这些问题吗?
为什么要使用struct? “运营商”之后的“()”是什么? 为什么要使用“>”而不是“<”由于包括结果列表在内的所有列表都按升序排列?
struct compare {
bool operator() (ListNode* &left, ListNode* &right) {
return left->val > right->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<ListNode *, vector<ListNode *>, compare> heap;
for (int i = 0; i < lists.size(); i++) {
if (lists[i]) heap.push(lists[i]);
}
ListNode *dummy = new ListNode(0);
ListNode *cur = dummy;
while (!heap.empty()) {
ListNode *min = heap.top();
heap.pop();
cur->next = min;
cur = min;
if (min->next) {
heap.push(min->next);
}
}
return dummy->next;
}
};
答案 0 :(得分:4)
您的struct compare
就是所谓的仿函数或函数对象。
struct compare
{
bool
operator() (const ListNode& left, const ListNode& right) const
{
return left.val > right.val;
}
};
void
example_usage(const ListNode& left, const ListNode& right, const compare cmp)
{
if (cmp(left, right))
std::cout << "left is greater" << std::endl;
else
std::cout << "right is greater" << std::endl;
}
(因为我使用了对指针的引用并使这些非const
过多地打扰了我,所以我更改了签名。)
在许多情况下使用函数指针是一种方便的替代方法。最重要的是,当在模板中使用时(如在您的示例中),编译器通常能够内联对运算符()
的调用。使用函数指针并不容易。
目前尚不清楚这是否与您的示例相关,但通常,仿函数的优势在于它可以在任何地方(也在函数体内)声明,而函数只能在全局范围内声明或作为类成员声明。这允许使用仿函数更好地封装。从C ++ 11开始,我们将 lambdas 作为另一种选择:
auto cmp = [](const ListNode& left, const ListNode& right)->bool{
return left.val > right.val;
};
它可以像仿函数一样使用。 (如果你给它一个lambda表达式,编译器很可能会创建一个仿函数。)
答案 1 :(得分:1)
为什么要使用struct?
这里没有必要使用结构,虽然它没有受到伤害。
&#34;()&#34;是什么? for&#34; operator&#34;?
查找运算符重载教程。
为什么要使用&#34;&gt;&#34;而不是&#34;&lt;&#34;由于包括结果列表在内的所有列表都按升序排列?
使用&lt;&lt;比较这些,所以我不知道为什么,除了尴尬。
此外,参数应为(const ListNode* left, const ListNode* right)
,如果在结构内部,则成员函数也应为const。这里没有必要参考它们。我还要考虑你是否需要一个指针和动态分配的数据结构。
答案 2 :(得分:0)
为什么要使用struct?
可以是struct
或class
。除了struct
的成员之外,它们基本上是相同的。public
成员默认为class
,成员private
为默认struct
,以及2.关于人们的一般观点应该使用class
用于POD(普通旧数据)和... operator()(...)
用于其他所有数据。
“运营商”之后的“()”是什么?
这个很有趣。 class
为函数调用运算符定义了重载。每当你调用一个函数时,你肯定会使用这个运算符,将参数封装在括号中,并使返回值成为表达式的结果。
在旁注中,带有重载函数调用运算符的struct
或functor
通常称为<
。
为什么要使用“&gt;”而不是“&lt;”由于包括结果列表在内的所有列表都按升序排列?
这也是另一个有趣的问题。我们的想法是, STL(标准模板库)旨在供几乎所有使用C ++的人使用,并且旨在为执行某些操作提供便利。因此,STL中的所有工具都可以用于任何类型,包括用户定义的类型。
但是,默认情况下,用户定义的类型没有>
和a > b
等运算符重载,因此用户必须重载它们。
b < a
的结果与<
基本相同。现在想象一下,如果其中一些工具使用>
,而其他工具则使用>
。每个人都必须使两个运营商都超负荷,即使它们只是彼此的补充,并且可以用来互相替代。
因此,设置了一个标准,以便STL仅使用{{1}}运算符,并且只要求您重载一个运算符。
在旁注中,您可以使用std::less模板化仿函数进行简单操作(如小于比较),std::function用于更复杂的操作,而不是编写自己的比较仿函数。 / p>
感谢您的阅读。